共用方式為


VirtualAlloc 函式 (memoryapi.h)

在呼叫程式的虛擬位址空間中保留、認可或變更頁面區域的狀態。 此函式配置的記憶體會自動初始化為零。

若要在另一個進程的位址空間中配置記憶體,請使用 VirtualAllocEx 函式。

語法

LPVOID VirtualAlloc(
  [in, optional] LPVOID lpAddress,
  [in]           SIZE_T dwSize,
  [in]           DWORD  flAllocationType,
  [in]           DWORD  flProtect
);

參數

[in, optional] lpAddress

要配置之區域的起始位址。 如果保留記憶體,則指定的位址會四捨五入到最接近的配置粒度倍數。 如果記憶體已保留且正在認可,位址會四捨五入至下一個頁面界限。 若要判斷頁面的大小和主計算機上的配置粒度,請使用 getSystemInfo 函式 。 如果此參數 NULL,則系統會決定要配置區域的位置。

如果這個位址位於您尚未透過呼叫 InitializeEnclave初始化的記憶體保護區內,VirtualAlloc 為該位址的記憶體保護區配置零頁。 頁面必須先前未認可,且不會使用 Intel Software Guard Extensions 程式設計模型的 EEXTEND 指令來測量。

如果位址位於您初始化的記憶體保護區內,則配置作業會失敗,並出現 ERROR_INVALID_ADDRESS 錯誤。 對於不支援易失記憶體管理的記憶體保護區而言,這是事實(亦即 SGX1)。 SGX2 記憶體保護區將允許配置,而且頁面必須在配置後由記憶體保護區接受。

[in] dwSize

區域的大小,以位元組為單位。 如果 lpAddress 參數 NULL,這個值會四捨五入至下一個頁面界限。 否則,配置的頁面會包含範圍中包含一或多個字節的所有頁面,範圍從 lpAddresslpAddress+dwSize。 這表示跨越頁面界限的 2 位元組範圍會導致這兩個頁面包含在配置的區域。

[in] flAllocationType

記憶體配置的類型。 此參數必須包含下列其中一個值。

價值 意義
MEM_COMMIT
0x00001000
為指定的保留記憶體分頁配置記憶體費用(從記憶體的整體大小和磁碟上的分頁檔案。 函式也保證當呼叫端稍後最初存取記憶體時,內容會是零。 除非實際存取虛擬位址,否則不會配置實際的實體頁面。

若要在一個步驟中保留和認可頁面,請使用 MEM_COMMIT | MEM_RESERVE呼叫 virtualAlloc

除非已保留整個範圍,否則嘗試藉由指定不含 MEM_RESERVEMEM_COMMIT 來認可特定位址範圍,且非NULLlpAddress 會失敗。 產生的錯誤碼 ERROR_INVALID_ADDRESS

嘗試認可已經認可的頁面,並不會讓函式失敗。 這表示您可以認可頁面,而不需要先判斷每個頁面的目前承諾狀態。

如果 lpAddress 指定記憶體保護區內的位址,則必須 flAllocationTypeMEM_COMMIT

MEM_RESERVE
0x00002000
保留進程虛擬位址空間的範圍,而不需在記憶體或磁碟上的分頁檔案中配置任何實際的實體記憶體。

您可以在後續呼叫 virtualAlloc 函式時認可保留的頁面。 若要在一個步驟中保留和認可頁面,請使用 MEM_COMMITMEM_RESERVE呼叫 virtualAlloc

其他記憶體配置函式,例如 mallocLocalAlloc,在釋放記憶體之前,無法使用保留的記憶體範圍。

MEM_RESET
0x00080000
表示 lpAddress 所指定記憶體範圍中的數據dwSize 已不再感興趣。 頁面不應該讀取或寫入至分頁檔案。 不過,稍後會再次使用記憶體區塊,因此不應予以認可。 這個值不能與任何其他值搭配使用。

使用此值不保證使用 MEM_RESET 運作的範圍將包含零。 如果您想要範圍包含零,請取消認可記憶體,然後重新認可它。

當您指定 MEM_RESET時,VirtualAlloc 函式會忽略 flProtect的值。 不過,您仍必須將 flProtect 設定為有效的保護值,例如 PAGE_NOACCESS

VirtualAlloc 如果您使用 MEM_RESET,且記憶體範圍會對應至檔案,則傳回錯誤。 只有在共享檢視對應至分頁檔案時才可接受。

MEM_RESET_UNDO
0x1000000
MEM_RESET_UNDO 應該只在先前成功套用 MEM_RESET 的位址範圍上呼叫。 它表示呼叫者感興趣的是 lpAddress 所指定記憶體範圍中的數據,dwSize,並嘗試反轉 MEM_RESET的效果。 如果函式成功,這表示指定位址範圍中的所有數據都保持不變。 如果函式失敗,則位址範圍中至少有一些數據已取代為零。

這個值不能與任何其他值搭配使用。 如果在先前未 MEM_RESET 的位址範圍上呼叫 MEM_RESET_UNDO,則行為未定義。 當您指定 MEM_RESET時,VirtualAlloc 函式會忽略 flProtect的值。 不過,您仍必須將 flProtect 設定為有效的保護值,例如 PAGE_NOACCESS

Windows Server 2008 R2、Windows 7、Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP:Windows 8 和 Windows Server 2012 之前不支援 MEM_RESET_UNDO 旗標。

此參數也可以指定下列值,如所示。

價值 意義
MEM_LARGE_PAGES
0x20000000
使用大型頁面支援 設定記憶體,

大小和對齊必須是大頁面最小值的倍數。 若要取得此值,請使用 getLargePageMinimum 函式

如果您指定這個值,您也必須指定 MEM_RESERVEMEM_COMMIT

MEM_PHYSICAL
0x00400000
保留位址範圍,可用來對應 位址視窗化延伸模組 (AWE) 頁面。

這個值必須與 MEM_RESERVE 搭配使用,而且沒有其他值。

MEM_TOP_DOWN
0x00100000
配置最高可能位址的記憶體。 這比一般配置慢,尤其是在有許多配置時。
MEM_WRITE_WATCH
0x00200000
讓系統追蹤在配置區域中寫入的頁面。 如果您指定此值,也必須指定 MEM_RESERVE

若要擷取自配置區域或重設寫入追蹤狀態以來已寫入的頁面位址,請呼叫 getWriteWatch 函式 。 若要重設寫入追蹤狀態,請呼叫 GetWriteWatchResetWriteWatch。 在釋放區域之前,記憶體區域仍會啟用寫入追蹤功能。

[in] flProtect

要配置之頁面區域的記憶體保護。 如果認可頁面,您可以指定任何一個 記憶體保護常數

如果 lpAddress 指定記憶體保護區內的位址,flProtect 不能是下列任何值:

  • PAGE_NOACCESS
  • PAGE_GUARD
  • PAGE_NOCACHE
  • PAGE_WRITECOMBINE

設定記憶體保護區的易失記憶體時,flProtect 參數必須 PAGE_READWRITEPAGE_EXECUTE_READWRITE

傳回值

如果函式成功,傳回值就是頁面所配置區域的基位址。

如果函式失敗,則傳回值 NULL。 若要取得擴充的錯誤資訊,請呼叫 GetLastError

言論

每個頁面都有相關聯的 頁面狀態VirtualAlloc 函式可以執行下列作業:

  • 認可保留頁面的區域
  • 保留免費頁面的區域
  • 同時保留並認可免費頁面的區域

VirtualAlloc 無法保留保留的頁面。 它可以認可已經認可的頁面。 這表示不論頁面是否已認可,都可以認可一系列頁面,而且函式不會失敗。

您可以使用 VirtualAlloc 來保留頁面區塊,然後對 virtualAlloc 進行其他呼叫,以認可來自保留區塊的個別頁面。 這可讓進程保留其虛擬位址空間的範圍,而不需要取用實體記憶體,直到需要為止。

如果 lpAddress 參數未 NULL,函式會使用 lpAddressdwSize 參數來計算要配置的頁面區域。 整個頁面範圍的目前狀態必須與 flAllocationType 參數所指定的配置類型相容。 否則,函式會失敗,且未配置任何頁面。 此相容性需求不會排除認可已認可的頁面,如先前所述。

若要執行動態產生的程式代碼,請使用 VirtualAlloc 來配置記憶體,並使用 VirtualProtect 函式來授與 PAGE_EXECUTE 存取權。

VirtualAlloc 函式可用來在指定行程的虛擬位址空間內保留記憶體 位址視窗延伸模組 (AWE) 區域。 然後,您可以使用此記憶體區域,將實體頁面對應到應用程式所需的虛擬記憶體和移出。 AllocationType 參數中必須設定 MEM_PHYSICALMEM_RESERVE 值。 不得設定 MEM_COMMIT 值。 頁面保護必須設定為 PAGE_READWRITE

VirtualFree 函式可以取消認可頁面、釋放頁面的記憶體,或同時解除認可和釋放認可的頁面。 它也可以釋放保留頁面,使其成為免費頁面。

建立將可執行的區域時,呼叫程式會負責確保透過適當的呼叫 FlushInstructionCache 快取一致性,一旦設定程式代碼就位。 否則,嘗試從新可執行區域執行程序代碼可能會產生無法預期的結果。

例子

如需範例,請參閱 保留和認可記憶體

要求

要求 價值
最低支援的用戶端 Windows XP [傳統型應用程式 |UWP 應用程式]
支援的最低伺服器 Windows Server 2003 [傳統型應用程式 |UWP 應用程式]
目標平臺 窗戶
標頭 memoryapi.h (包括 Windows.h、Memoryapi.h)
連結庫 onecore.lib
DLL Kernel32.dll

另請參閱

記憶體管理功能

虛擬記憶體函式

VirtualAllocEx

VirtualFree

VirtualLock

VirtualProtect

VirtualQuery

VBS 記憶體保護區中提供的 Vertdll API