HeapCreate 函式 (heapapi.h)
建立可由呼叫進程使用的私人堆積物件。 函式會在進程的虛擬位址空間中保留空間,併為這個區塊的指定初始部分配置實體記憶體。
語法
HANDLE HeapCreate(
[in] DWORD flOptions,
[in] SIZE_T dwInitialSize,
[in] SIZE_T dwMaximumSize
);
參數
[in] flOptions
堆積配置選項。 這些選項會透過呼叫堆積函式,影響對新堆積的後續存取。 此參數可以是 0 或下列一或多個值。
值 | 意義 |
---|---|
|
如果硬體強制執行 數據執行防護,則從這個堆積配置的所有記憶體區塊都允許程式代碼執行。 在從堆積執行程式碼的應用程式中使用此旗標堆積。 如果未指定 HEAP_CREATE_ENABLE_EXECUTE ,且應用程式嘗試從受保護的頁面執行程序代碼,則應用程式會收到狀態代碼 STATUS_ACCESS_VIOLATION的例外狀況。 |
|
例如,系統會引發例外狀況來指出失敗 (,) 呼叫 HeapAlloc 和 HeapReAlloc,而不是傳回 NULL。 |
|
當堆積函式存取此堆積時,不會使用串行化存取。 此選項適用於所有後續的堆積函數調用。 或者,您可以在個別堆積函數調用上指定此選項。
無法針對使用此選項建立的堆積啟用低片段堆積 (LFH) 。 使用此選項建立的堆積無法鎖定。 如需串行化存取的詳細資訊,請參閱本主題的一節。 |
[in] dwInitialSize
堆積的初始大小,以位元組為單位。 這個值會決定堆積認可的初始記憶體數量。 此值會四捨五入為系統頁面大小的倍數。 此值必須小於 dwMaximumSize。
如果此參數為 0,函式會認可一頁。 若要判斷主計算機上的頁面大小,請使用 GetSystemInfo 函式。
[in] dwMaximumSize
堆積的大小上限,以位元組為單位。 HeapCreate 函式會將 dwMaximumSize 四捨五入為系統頁面大小的倍數,然後在處理程式的虛擬位址空間中保留該大小的區塊。 如果 HeapAlloc 或 HeapReAlloc 函式所做的配置要求超過 dwInitialSize 所指定的大小,則系統會認可堆積的額外記憶體分頁,最多可達堆積的大小上限。
如果 dwMaximumSize 不是零,堆積大小是固定的,而且無法成長超過大小上限。 此外,可從堆積配置的最大記憶體區塊對於 32 位進程而言稍微小於 512 KB,而 64 位進程則稍微小於 1,024 KB。 配置較大區塊的要求會失敗,即使堆積的大小上限足以包含區塊也一樣。
如果 dwMaximumSize 為 0,堆積的大小可能會成長。 堆積的大小只受限於可用的記憶體。 配置大於固定大小堆積限制的記憶體區塊的要求不會自動失敗;相反地,系統會呼叫 VirtualAlloc 函式,以取得大型區塊所需的記憶體。 需要配置大型記憶體區塊的應用程式應該將 dwMaximumSize 設定為 0。
傳回值
如果函式成功,則傳回值是新建立堆積的句柄。
如果函式失敗,傳回值為 NULL。 若要取得擴充的錯誤資訊,請呼叫 GetLastError。
備註
HeapCreate 函式會建立私用堆積物件,呼叫進程可以使用 HeapAlloc 函式來配置記憶體區塊。 初始大小會決定一開始為堆積配置的認可頁面數目。 大小上限決定保留頁數的總數。 這些頁面會在處理程式的虛擬位址空間中建立區塊,讓堆積成長。 如果 HeapAlloc 的要求超過目前認可的頁面大小,如果實體記憶體可用,系統會自動從此保留空間認可其他頁面。
Windows Server 2003 和 Windows XP: 根據預設,新建立的私人堆積是標準堆積。 若要啟用低片段堆積,請使用私用堆積的句柄呼叫 HeapSetInformation 函式。
私人堆積物件的記憶體只能供建立它的進程存取。 如果動態連結庫 (DLL) 建立私人堆積,則會在呼叫 DLL 之進程的地址空間中建立堆積,而且只能存取該程式。
系統會使用來自私人堆積的記憶體來儲存堆積支持結構,因此並非所有指定的堆積大小都可供進程使用。 例如,如果 HeapAlloc 函式從大小上限為 64K 的堆積要求 64 KB (K) ,則要求可能會因為系統額外負荷而失敗。
如果未指定 HEAP_NO_SERIALIZE (簡單的預設) ,則堆積會在呼叫程式中串行化存取。 當兩個或多個線程同時嘗試配置或釋放來自相同堆積的區塊時,串行化可確保互斥。 串行化有一小部分的效能成本,但每當多個線程配置和釋放來自相同堆積的記憶體時,都必須使用它。 HeapLock 和 HeapUnlock 函式可用來封鎖及允許存取串行化的堆積。
設定 HEAP_NO_SERIALIZE 可排除堆積上的相互排除。 如果沒有串行化,使用相同堆積句柄的兩個或多個線程可能會嘗試同時配置或釋放記憶體,這可能會導致堆積損毀。 因此, HEAP_NO_SERIALIZE 只能在下列情況下安全地使用:
- 進程只有一個線程。
- 進程有多個線程,但只有一個線程會呼叫特定堆積的堆積函式。
- 進程有多個線程,而且應用程式會提供自己的機制,以排除特定堆積。
如果在以 HEAP_NO_SERIALIZE 旗標建立的堆積上呼叫 HeapLock 和 HeapUnlock 函式,則結果為未定義。
若要取得進程預設堆積的句柄,請使用 GetProcessHeap 函式。 若要取得呼叫進程使用中之預設堆積和私人堆積的句柄,請使用 GetProcessHeaps 函式。
範例
規格需求
最低支援的用戶端 | Windows XP [傳統型應用程式 |UWP 應用程式] |
最低支援的伺服器 | Windows Server 2003 [傳統型應用程式 |UWP 應用程式] |
目標平台 | Windows |
標頭 | heapapi.h (包含 Windows.h) |
程式庫 | Kernel32.lib |
DLL | Kernel32.dll |