鱼C论坛

 找回密码
 立即注册
查看: 3231|回复: 0

[API档案] HeapReAlloc

[复制链接]
发表于 2016-7-3 23:44:37 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
注:本文档由 百日维新 翻译,小甲鱼校对。

原文链接 -> 传送门

函数功能:

HeapReAlloc 函数用于重新从堆分配内存块。您可以调整内存块的大小,改变内存块其他属性。分配的内存不可移动。


API 函数原型:

注释:_In_ 说明该参数是输入的。
  1. LPVOID WINAPI HeapReAlloc(
  2.   _In_ HANDLE hHeap,
  3.   _In_ DWORD  dwFlags,
  4.   _In_ LPVOID lpMem,
  5.   _In_ SIZE_T dwBytes
  6. );
复制代码


参数解析:

参数 含义
hHeap1. 指向将要被分配的堆内存句柄

2. 该句柄由 HeapCreate 函数或者 GetProcessHeap 函数获得
dwFlags1. 重新分配堆内存选项

2. 如果使用 HeapCreate 函数创建堆,这些值将会覆盖之前对应的值

3. 该参数可以为以下的一个或多个:
含义
HEAP_GENERATE_EXCEPTIONS
(0x00000004)
1. 系统抛出异常表明函数调用失败,比如内存溢出时抛出异常,如果抛出异常就不返回 NULL

2. 应该在 HeapCreate 函数创建堆时指定 HEAP_GENERATE_EXCEPTIONS 参数值,以确保在调用该函数发生错误时可以抛出异常。在这种情况下,没有必要调用该函数再另外指定 HEAP_GENERATE_EXCEPTIONS 参数值。
HEAP_NO_SERIALIZE
(0x00000001)
1. 该参数分配的内存不使用序列化访问。更多信息,参见备注

2. 应该在 HeapCreate 函数创建堆时指定 HEAP_NO_SERIALIZE 参数值,以确保在调用该函数分配内存不能序列化访问。在这种情况下,没有必要调用该函数再另外指定 HEAP_NO_SERIALIZE 参数值

3. 当访问进程堆时,不应该指定这个参数值。系统可能在应用程序的进程中创建额外的线程,比如同时访问进程堆的复制句柄
HEAP_REALLOC_IN_PLACE_ONLY
(0x00000010)
当重新分配一个内存块时,可以不移动。如果不指定这个参数值,则函数移动内存块到一个新的位置。如果指定这个参数值,分配的内存块不能调整大小且不能移动,函数失败,原来的内存块不改变
HEAP_ZERO_MEMORY
(0x00000008)
如果重新请求分配很大的内存块,超出原大小的内存被初始化为 0。内存块原大小的内容不受影响
lpMem指向函数重新分配的内存块指针。该指针由 HeapAlloc 函数或 HeapReAlloc 函数返回
dwBytes1. 新内存块的大小,字节单位。使用该函数可以增加或减少内存块的大小

2. 如果 hHeap 指向一个不增长堆,dwBytes 必须小于 0x7FFF8。您可以使用 HeapCreate 函数指定一个非 0 值创建不增长堆


返回值:

1. 如果函数调用成功,返回值为指向重新分配的内存块指针;

2. 如果函数调用失败,不指定 HEAP_GENERATE_EXCEPTIONS,则返回 NULL。

3. 如果函数调用失败,且指定 HEAP_GENERATE_EXCEPTIONS,函数会生成下列两个异常之一。异常取决于堆溢出性质。若想获取更多信息,查阅 GetExceptionCode 宏。

异常代码 描述
STATUS_NO_MEMORY由于缺少可用内存或者是堆溢出导致分配失败
STATUS_ACCESS_VIOLATION由于堆溢出或者函数参数不正确导致分配失败

如果先前没有调用 SetLastError 函数,那么当 HeapReAlloc 函数调用失败时,应用程序无法通过调用 GetLastError 函数获取更多错误信息。


备注:

1. 如果函数调用成功,至少会分配用户请求的内存大小。

2. 如果函数调用失败,原内存没有释放且原句柄和指针仍然有效。

3. HeapReAlloc 函数保留被重新分配的内存内容,即使新内存分配在不同的位置。保留进程的内存内容涉及到非常耗时的内存复制操作。

4. 使用 HeapFree 函数释放内存。

5. 当两个或者多个线程尝试同时分配或者释放相同堆的内存块。这对序列化存在小小的影响,但是它必须被使用无论何时多个线程分配或者释放相同堆的内存块。使用 HEAP_NO_SERIALIZE 参数值消除堆中互斥。如果没有序列化,两个或者多个使用相同堆的线程可能会尝试同时分配或者释放内存,可能引起堆溢出。因此,HEAP_NO_SERIALIZE 参数值在下列情况是安全的:

  • 进程只有一个线程。
  • 进程有多个线程,但一个堆中只有一个线程在使用。
  • 进程有多个线程,但应用程序使用堆时,有互斥解决方案。


需求:

Minimum supported client Windows XP [桌面应用程序 | Windows Store 程序]
Minimum supported server Windows 2003 服务器版 [桌面应用程序 | Windows Store 程序]
Minimum supported phone Windows Phone 8
HeaderHeapApi.h (包含于 Windows.h);
WinBase.h 在 Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP 上(包含于 Windows.h)
Library Kernel32.lib
DLL Kernel32.dll


【API档案】版权归鱼C工作室(www.fishc.com)所有,转载请注明来源。


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-12 08:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表