1. 가상 주소 조작
가상 메모리를 사용함으로서 실제 주소와 가상 주소가 분리된다. malloc, new 같은 함수는 가상 메모리를 실질적으로 할당하는데, 이렇게 메모리 차원에서 할당을 하지 않고 가상주소 차원에서 조작할 수 있다. 이 경우 단위는 페이지이며 처리해야 할 수준이 주소에서 끝나므로 단위가 큰 경우 효율적으로 사용할 수 있다.
LPVOID VirtualAlloc ( LPVOID lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD flProtect);
BOOL VirtualFree ( LPVOID lpAddress, DWORD dwSize, DWORD dwFreeType)
flAllocationType 은 아래의 플래그이다.
flProtect 는 아래의 플래그이다.
아래는 dwFreeType 의 플래그이다.
해제 함수의 경우 0 이 성공이고 -1 이 실패임에 주의.
ptr = (int*)VirtualAlloc(NULL, sizeof(int)*10, MEM_RESERVE_PAGE, PAGE_READWRITE);
ptr = (int*)VirtualAlloc(ptr, sizeof(int)*10, MEM_COMMIT, PAGE_READWRITE);
위 코드의 방식으로 사용해서 페이지 예약, 확정을 조절하는게 주요 사용법이다.
대용량 메모리의 할당을 유동적으로 조절할 때 주로 사용한다.
2. 메모리 맵 파일
용량이 큰 파일의 경우 메모리에 다 올릴 수가 없다. 그런 경우 가상메모리의 일부를 디스크와 연결하여 메모리에 파일을 전체를 올리지 않고 페이지 단위로 파일의 부분만 올리는데 이걸 메모리 맵핑이라고 한다.
또한 Win32에서 프로세스간 메모리를 공유하는 유일한 합법적인 방법이다. 여러개의 프로세스가 하나의 메모리 맵 파일을 동시에 접근할 수 있기 때문이다.
HANDLE CreateFileMapping ( HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCTSTR lpName);
hFile 은 CreateFile로 오픈한 핸들이다. 이 때 공유 설정은 0 으로 하는 것이 바람직하다.
CreateFile 로는 핸들만 얻을 뿐 버퍼에 내용을 채우지 않는다. 오해주의.
공유 메모리를 위해선 INVALID_HANDLE_VALUE 를 넣는다.
lpFileMappingAttributes 는 보안 정보와 관련되었다 하는데 대개 NULL 을 준다고 한다.
lpProtect 는 아래의 플래그이다.
dwMaximumSizeHigh, dwMaximumSizeLow 는 합쳐져서 생성될 맵핑 오브젝트의 최대 크기를 지정한다.
0, 0 을 지정하면 hFile 에 지정된 파일의 크기가 사용된다.
메모리 공유시 0, MAXSHAREDMEMORY 를 사용한다.
lpName 은 생성할 오브젝트의 이름이다. 필요없을 경우 NULL 을 넣는다.
공유 메모리를 사용시
LPVOID MapViewOfFile ( HANDLE hFileMappingObject, DWORD dwDesireAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, DWORD dwNumberOfBytesToMaps );
위 함수로 파일의 일부분을 메모리에 올린다.
dwDesireAccess 는 아래의 플래그이다. flProtect 인수와 호환되야한다.
dwNumberOfBytesToMaps 은 맵핑할 뷰의 크기를 지정한다. 0 이면 전체이다.
BOOL UnmapViewOfFile (LPCVOID lpBaseAddress );
MapViewOfFile 에서 얻어온 포인터는 이 함수로 해제한다.
CreateFileMapping 으로 생성한 파일 핸들은 CreateFile 과 똑같이 CloseHandle 로 해제한다.
아래는 책에 있는 메모리 공유 예제인데 신기방기.
클래스 이름만 바꿔서 파일 두개 만들어서 실행하면 된다.