M內存分配
內存分配函數
MFCWin32或者C語言的內存分配API,有四種內存分配API可供使用。
Win32的堆分配函數
每一個進程都可以使用堆分配函數創建一個私有的堆──調用進程地址空間的一個或者多個頁面。DLL創建的私有堆必定在調用DLL的進程的地址空間內,只能被調用進程訪問。
HeapCreate用來創建堆;HeapAlloc用來從堆中分配一定數量的空間,HeapAlloc分配的內存是不能移動的;HeapSize可以確定從堆中分配的空間的大小;HeapFree用來釋放從堆中分配的空間;HeapDestroy銷毀創建的堆。
Windows傳統的全局或者局部內存分配函數
由於Win32采用平面內存結構模式,Win32下的全局和局部內存函數除了名字不同外,其他完全相同。任一函數都可以用來分配任意大小的內存(僅僅受可用物理內存的限制)。用法可以和Win16下基本一樣。
Win32下保留這類函數保證了和Win16的兼容。
C語言的標准內存分配函數
C語言的標准內存分配函數包括以下函數:
malloc,calloc,realloc,free,等。
這些函數最後都映射成堆API函數,所以,malloc分配的內存是不能移動的。這些函數的調式版本為
malloc_dbg,calloc_dbg,realloc_dbg,free_dbg,等。
Win32的虛擬內存分配函數
虛擬內存API是其他API的基礎。虛擬內存API以頁為最小分配單位,X86上頁長度為4KB,可以用GetSystemInfo函數提取頁長度。虛擬內存分配函數包括以下函數:
LPVOID VirtualAlloc(LPVOID lpvAddress,
DWORD cbSize,
DWORD fdwAllocationType,
DWORD fdwProtect);
該函數用來分配一定范圍的虛擬頁。參數1指定起始地址;參數2指定分配內存的長度;參數3指定分配方式,取值MEM_COMMINT或者MEM_RESERVE;參數4指定控制訪問本次分配的內存的標識,取值為PAGE_READONLY、PAGE_READWRITE或者PAGE_NOACCESS。
LPVOID VirtualAllocEx(HANDLE process,
LPVOID lpvAddress,
DWORD cbSize,
DWORD fdwAllocationType,
DWORD fdwProtect);
該函數功能類似於VirtualAlloc,但是允許指定進程process。VirtaulFree、VirtualProtect、VirtualQuery都有對應的擴展函數。
BOOL VirtualFree(LPVOID lpvAddress,
DWORD dwSize,
DWORD dwFreeType);
該函數用來回收或者釋放分配的虛擬內存。參數1指定希望回收或者釋放內存的基地址;如果是回收,參數2可以指向虛擬地址范圍內的任何地方,如果是釋放,參數2必須是VirtualAlloc返回的地址;參數3指定是否釋放或者回收內存,取值為MEM_DECOMMINT或者MEM_RELEASE。
BOOL VirtualProtect(LPVOID lpvAddress,
DWORD cbSize,
DWORD fdwNewProtect,
PDWORD pfdwOldProtect);
該函數用來把已經分配的頁改變成保護頁。參數1指定分配頁的基地址;參數2指定保護頁的長度;參數3指定頁的保護屬性,取值PAGE_READ、PAGE_WRITE、PAGE_READWRITE等等;參數4用來返回原來的保護屬性。
DWORD VirtualQuery(LPCVOID lpAddress,
PMEMORY_BASIC_INFORMATION lpBuffer,
DWORD dwLength
);
該函數用來查詢內存中指定頁的特性。參數1指向希望查詢的虛擬地址;參數2是指向內存基本信息結構的指針;參數3指定查詢的長度。
BOOL VirtualLock(LPVOID lpAddress,DWORD dwSize);
該函數用來鎖定內存,鎖定的內存頁不能交換到頁文件。參數1指定要鎖定內存的起始地址;參數2指定鎖定的長度。
BOOL VirtualUnLock(LPVOID lpAddress,DWORD dwSize);
參數1指定要解鎖的內存的起始地址;參數2指定要解鎖的內存的長度。
C++的new 和 delete