堆的物理存储器来自页交换文件。
进程默认堆
1堆在进程的地址空间上。
2.默认情况下,进程堆的大小为1MB.
3.动态链接库是没有所谓的进程默认堆。
4.获取进程的默认堆的函数 getprocessheap
额外堆
1.创建额外堆 HeapCreate
HANDLE WINAPI HeapCreate(
__in DWORD flOptions,
__in SIZE_T dwInitialSize,
__in SIZE_T dwMaximumSize );
第一个参数flOptions用于修改如何在堆栈上执行各种操作。你可以设定0、HEAP_NO_SERIALIZE、HEAP_GENERATE_EXCEPTIONS、HEAP_CREATE_ENABLE_EXECUTE或者是这些标志的组合。
HEAP_NO_SERIALIZE:对堆的访问是非独占的,如果一个线程没有完成对堆的操作,其它线程也可以进程堆操作,这个开关是非常危险的,应尽量避免使用。
HEAP_GENERATE_EXCEPTIONS:当堆分配内存失败时,会抛出异常。如果不设置,则返回NULL。
HEAP_CREATE_ENALBE_EXECUTE:堆中存放的内容是可以执行的代码。如果不设置,意味着堆中存放的是不可执行的数据
dwInitialSize:一开始调拨给堆的字节数。
dwMaximumSize :堆等增长到最大大小。如果dwMaximumSize = 0,表示没有指定上限。
从堆分配内存块HeapAlloc
LPVOID HeapAlloc(
HANDLE hHeap,
DWORD dwFlags,
SIZE_T dwBytes,
);
hHeap:要分配堆的句柄,可以通过HeapCreate()函数或GetProcessHeap()函数获得
dwFlags:
值 | 意义 |
---|---|
HEAP_GENERATE_EXCEPTIONS | 如果分配错误将会抛出异常,而不是返回NULL。异常值可能是STATUS_NO_MEMORY, 表示获得的内存容量不足,或是STATUS_ACCESS_VIOLATION,表示存取不合法。 |
HEAP_NO_SERIALIZE | 不使用连续存取。 |
HEAP_ZERO_MEMORY | 将分配的内存全部清零。 |
dwBytes:要分配堆的字节数。
调整内存块的大小
LPVOID HeapReAlloc(
HANDLE hHeap,
DWORD dwFlags,
LPVOID pvMem,
SIZE_T pvMem,
);
dwFlags:
HEAP_ZERO_MEMORY:只有增大内存块时才有用,减小不起作用。
HEAP_REALLOC_IN_PLACE_ONLY 不要移动内存块,如果不移动也能增大则返回原来的地址。
pvMem:内存块当前的地址
pvMem:新的大小
获取内存块的大小
SIZE_T heapszie{
HANDLE hHeap;
DWORD fdwFlags;
LPCVOID pvMen);
fdwFlags:可以是0或者HEAP_NO_SERIALIZE
释放内存块
BOOL HeapFree(
HANDLE hHeap,
DWORD fdwFlags,
LPVOID lpMem
)
fdwFlags:可以是0或者HEAP_NO_SERIALIZE
销毁堆 heapdestroy
释放所有的内存块,系统回收占用的物理存储器和地址空间区域。
不允许在进程终止前,销毁进程的默认堆。
引申到c++操作符 new和delete的使用。
对比c运行库函数malloc 和 free