与堆有关的API

进程初始化的时候,系统会在进程的地址空间中创建一个堆。这个堆被称为进程的默认堆。
除了进程的默认堆,我们可以在进程的地址空间中创建额外的堆。由于以下原因,我们可能希望在应用程序中创建额外的堆:
• 对组件进行保护
• 更有效地内存管理
• 局部访问
• 避免线程同步的开销
• 快速释放

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_CREATE_ENABLE_EXECUTE。

第二参数dwInitialSize表示开始时分给堆的字节数。

第三参数dwMaximumSize表示所能增长到的最大大小,如果指定为0的话,则堆可以在需要的情况下不断增大。

GetProcessHeap

用以获取和调用进程的堆句柄.(默认堆)
这个函数返回一个指向调用进程的堆的句柄。这个句柄可以被用于函数HeapAlloc , HeapReAlloc , HeapFree , HeapSize .

HANDLE GetProcessHeap(VOID);
参数:无。
返回值:成功:调用函数的进程的堆句柄。失败:NULL

HeapAlloc

从堆里分配内存块,只需调用HeapAlloc()函数
LPVOID
WINAPI
HeapAlloc(
In HANDLE hHeap,
In DWORD dwFlags,
In SIZE_T dwBytes
);
这里说一下第二参数,用来指定一些标志,会对分配结果产生影响。
HEAP_GENERATE_EXCEPTIONS:如果分配错误将会抛出异常,而不是返回NULL。异常值可能是STATUS_NO_MEMORY, 表示获得的内存容量不足,或是STATUS_ACCESS_VIOLATION,表示存取不合法。
HEAP_NO_SERIALIZE:不使用连续存取。
HEAP_ZERO_MEMORY:将分配的内存全部清零。

如果指定了HEAP_GENERATE_EXCEPTIONS,则抛出异常,而不返回NULL:
STATUS_NO_MEMORY:由于缺少可用内存或者是堆损坏导致分配失败。
STATUS_ACCESS_VIOLATION:由于堆损坏或者是不正确的函数参数导致分配失败。.

HeapSetInformation

对一个堆设定启用一些特性。
BOOL WINAPI HeapSetInformation(
__in_opt HANDLE HeapHandle,
__in HEAP_INFORMATION_CLASS HeapInformationClass,
__in PVOID HeapInformation,
__in SIZE_T HeapInformationLength
);
Heaphandle: 堆的句柄

HeapInformationClass: HEAP_INFORMATION_CLASS 一个枚举, 取值有2个:HeapCompatibilityInformation和HeapEnableTerminationOnCorruption

HeapInformation:堆的信息

HeapInformationLength: 堆信息的长度

HeapReAlloc

调整内存块的大小, 调整内存块的大小事通过调用HeapReAlloc函数来完成的:
PVOID HeapReAlloc(
HANDLE hHeap,
DWORD fdwFlags,
PVOID pvMem,//需要调整内存块的当前地址
SIZE_T dwBytes);//内存块的新大小

HeapSize

获得内存块大小
分配一块内存后,可以调用HeapSize函数来得到这块内存的实际大小:
SIZE_T HeapSize(
HANDLE hHeap,
DWORD fdwFlags,
LPCVOID pvMem);//内存块地址

HeapFree

释放内存块
不再需要一块内存的时候,我们可以调用HeapFree来释放它:
BOOL HeapFree(
HANDLE hHeap,
DWORD fdwFlags,
PVOID pvMem);

HeapDestroy

销毁堆
如果应用程序不再需要自己创建的堆,则可以调用HeapDestroy来销毁它:
BOOL HeapDestroy(HANDLE hHeap);

调用HeapDestroy会释放堆中包含的所有内存块,同时系统会收回堆所占用的物理存储器和地址空间区域。

HeapCompact

为了让堆中闲置的内存块能重新结合在一起,并撤销调拨给堆中闲置内存块的存储器,可以调用下面的函数:
UINT HeapCompact(
HANDLE hHeap,
DWORD fdwFlags);
下面两个函数用于线程同步:
BOOL HeapLock(HANDLE hHeap);
BOOL HeapUnlock(HANDLE hHeap);

HeapValidate

检测堆是否有效
BOOL HeapValidate( HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem );
其中hHeap为要检查的堆的句柄,dwFlags为标志,一般设置为0, lpMem如果为NULL就检查整个堆正确性,否则仅仅检查lpMem指向的内存块的有效性。函数返回TRUE表示堆或内存块有效,返回FALSE则表示状态已经被破坏。

Malloc

L=(int *)malloc(sizeof(int));

malloc()找到可用内存中一个大小适合的块。内存是匿名的;也就是说,malloc()分配了内存,但没有为它指定名字。然而,它却可以返回那块内存第一个字节的地址。因此,可以把那个地址赋值给一个指针变量,并使用该指针来访问那块内存。

  1. 首先malloc()函数返回的是void *类型,所以用的时候要进行强制类型转换
  2. malloc函数用完后,记得使用free()函数来释放空间,不然只分配不释放会出问题,free()的参数应是一指针,指向由malloc()分配的内存块;函数free()的参数是先前malloc()返问的地址,它释放先前分配的内存。

VirtualAlloc

VirtualAlloc是一个Windows API函数,它包含在windows系统文件Kernel32.dll中,编程时直接使用就可以了,不需要再下载。该函数的功能是在调用进程的虚地址空间,预定或者提交一部分页,如果用于内存分配的话,并且分配类型未指定MEM_RESET,则系统将自动设置为0;
此虚拟内存非彼虚拟内存,此虚拟内存实际上指的是虚拟地址空间
LPVOID VirtualAlloc{
LPVOID lpAddress, // 要分配的内存区域的地址
DWORD dwSize, // 分配的大小
DWORD flAllocationType, // 分配的类型
DWORD flProtect // 该内存的初始保护属性
};
1.这个函数可以用来对虚拟地址空间进行分配(保留操作MEM_RESERVE)
2.这个函数可以把已经保留的虚拟地址提交到物理存储器(MEM_COMMIT)
3.这个函数可以使RAM上的内容无效(MEM_RESET)

参考:https://blog.csdn.net/shenzi/article/details/4689695#t1
https://blog.csdn.net/junbopengpeng/article/details/29364487

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值