heapReAlloc 函数 (heapapi.h)

从堆中重新分配内存块。 使用此函数可以调整内存块的大小并更改其他内存块属性。 分配的内存不可移动。

语法

DECLSPEC_ALLOCATOR LPVOID HeapReAlloc(
  [in] HANDLE                 hHeap,
  [in] DWORD                  dwFlags,
  [in] _Frees_ptr_opt_ LPVOID lpMem,
  [in] SIZE_T                 dwBytes
);

参数

[in] hHeap

要从中重新分配内存的堆的句柄。 此句柄是由 HeapCreateGetProcessHeap 函数返回的 。

[in] dwFlags

堆重新分配选项。 使用 HeapCreate 函数创建堆时,指定值将替代 flOptions 参数中指定的相应值。 此参数可使用以下一个或多个值。

含义
HEAP_GENERATE_EXCEPTIONS
0x00000004
操作系统引发异常以指示函数失败(例如内存不足的情况),而不是返回 NULL

若要确保为此函数的所有调用生成异常,请在对 HeapCreate 的调用中指定HEAP_GENERATE_EXCEPTIONS。 在这种情况下,无需在此函数调用中额外指定 HEAP_GENERATE_EXCEPTIONS

HEAP_NO_SERIALIZE
0x00000001
不会使用序列化访问。 有关详细信息,请参阅“备注”。

若要确保对此函数的所有调用禁用序列化访问,请在对 HeapCreate 的调用中指定HEAP_NO_SERIALIZE。 在这种情况下,无需在此函数调用中额外指定 HEAP_NO_SERIALIZE

访问进程堆时不应指定此值。 系统可能会在应用程序的进程中创建其他线程,例如同时访问进程堆的 CTRL+C 处理程序。

HEAP_REALLOC_IN_PLACE_ONLY
0x00000010
重新分配内存块时不能移动。 如果未指定此值,该函数可能会将块移动到新位置。 如果指定了此值,并且无法在不移动的情况下调整块的大小,则函数将失败,使原始内存块保持不变。
HEAP_ZERO_MEMORY
0x00000008
如果重新分配请求的大小更大,则超出原始大小的其他内存区域将初始化为零。 内存块的内容与其原始大小一起不受影响。

[in] lpMem

指向函数重新分配的内存块的指针。 此指针由先前对 HeapAllocHeapReAlloc 函数的调用返回。

[in] dwBytes

内存块的新大小(以字节为单位)。 使用此函数可以增加或减小内存块的大小。

如果 hHeap 参数指定的堆是“不可增长”堆, 则 dwBytes 必须小于 0x7FFF8。 可以通过调用具有非零值的 HeapCreate 函数来创建不可增长的堆。

返回值

如果函数成功,则返回值是指向重新分配的内存块的指针。

如果函数失败,并且您尚未指定 HEAP_GENERATE_EXCEPTIONS,则返回值为 NULL

如果函数失败,并且已指定 HEAP_GENERATE_EXCEPTIONS,该函数可能会生成下表中列出的任一异常。 有关详细信息,请参阅 GetExceptionCode

异常代码 说明
STATUS_NO_MEMORY 由于缺少可用内存或堆损坏,分配尝试失败。
STATUS_ACCESS_VIOLATION 由于堆损坏或函数参数不正确,分配尝试失败。

HeapReAlloc 返回的内存对齐方式在 WinNT.h 中MEMORY_ALLOCATION_ALIGNMENT

#if defined(_WIN64) || defined(_M_ALPHA)
#define MEMORY_ALLOCATION_ALIGNMENT 16
#else
#define MEMORY_ALLOCATION_ALIGNMENT 8
#endif

如果函数失败,则不调用 SetLastError。 应用程序无法调用 GetLastError 以获取扩展错误信息。

注解

如果 HeapReAlloc 成功,它将至少分配请求的内存量。

如果 HeapReAlloc 失败,则不会释放原始内存,并且原始句柄和指针仍然有效。

可以保证 HeapReAlloc 保留要重新分配的内存的内容,即使新内存是在不同的位置分配的。 保留内存内容的过程涉及可能非常耗时的内存复制操作。

若要释放 HeapReAlloc 分配的内存块,请使用 HeapFree 函数。

当两个或多个线程尝试从同一堆同时分配或释放块时,序列化可确保相互排斥。 序列化的性能成本很小,但每当多个线程从同一堆分配和释放内存时,必须使用它。 设置 HEAP_NO_SERIALIZE 值可消除堆上的相互排斥。 如果不进行序列化,使用同一堆句柄的两个或多个线程可能会尝试同时分配或释放内存,这可能会导致堆损坏。 因此,只能在以下情况下安全地使用 HEAP_NO_SERIALIZE 值:

  • 进程只有一个线程。
  • 进程有多个线程,但只有一个线程调用特定堆的堆函数。
  • 进程具有多个线程,应用程序为特定堆提供自身的相互排斥机制。

要求

要求
最低受支持的客户端 Windows XP [桌面应用 | UWP 应用]
最低受支持的服务器 Windows Server 2003 [桌面应用 | UWP 应用]
目标平台 Windows
标头 heapapi.h (包括 Windows.h)
Library Kernel32.lib
DLL Kernel32.dll

另请参阅

堆函数

HeapAlloc

HeapFree

内存管理函数

VBS enclave 中可用的 Vertdll API