VirtualAlloc是一個Windows API函式,該函式的功能是在調用進程的虛地址空間,預定或者提交一部分頁。
簡單點的意思就是申請記憶體空間
基本介紹
- 中文名:VirtualAlloc
- 類屬:一個Windows API函式
- 包含在:windows系統檔案Kernel32.dll中
- VC聲明:LPVOID VirtualAlloc
VC概述,VC聲明,說明,參數表說明,返回值,筆記,
VC概述
VirtualAlloc是一個Windows API函式,它包含在windows系統檔案Kernel32.dll中,編程時直接使用就可以了,不需要再下載。
該函式的功能是在調用進程的虛地址空間,預定或者提交一部分頁
如果用於記憶體分配的話,並且分配類型未指定MEM_RESET,則系統將自動設定為0;
VC聲明
LPVOID VirtualAlloc{
LPVOID lpAddress, // 要分配的記憶體區域的地址
DWORD dwSize, // 分配的大小
DWORD flAllocationType, // 分配的類型
DWORD flProtect // 該記憶體的初始保護屬性
};
說明
該函式的功能是在調用進程的虛地址空間,預定或者提交一部分頁
如果用於記憶體分配的話,並且分配類型未指定MEM_RESET,則該記憶體自動被初始化為0;
參數表說明
LPVOID lpAddress, 分配記憶體區域的地址。當你使用VirtualAlloc來提交一塊以前保留的記憶體塊的時候,lpAddress參數可以用來識別以前保留的記憶體塊。如果這個參數是NULL,系統將會決定分配記憶體區域的位置,並且按64-KB向上取整(roundup)。
SIZE_T dwSize, 要分配或者保留的區域的大小。這個參數以位元組為單位,而不是頁,系統會根據這個大小一直分配到下頁的邊界DWORD
flAllocationType, 分配類型 ,你可以指定或者合併以下標誌:MEM_COMMIT,MEM_RESERVE和MEM_TOP_DOWN。
DWORD flProtect 指定了被分配區域的訪問保護方式
分配類型 功能
可能的數值 | 含義 |
---|---|
MEM_COMMIT 0x1000 | 為指定地址空間提交物理記憶體。這個函式初始化內在為零 試圖提交已提交的記憶體頁不會導致函式失敗。這意味著您可以在不確定當前頁的當前提交狀態的情況下提交一系列頁面。 如果尚未保留記憶體頁,則設定此值會導致函式同時保留並提交記憶體頁。 |
MEM_RESERVE 0x2000 | 保留指定地址空間,不分配物理記憶體。 這樣可以阻止其他記憶體分配函式malloc和LocalAlloc等再使用已保留的記憶體範圍,直到它被被釋放。 當使用上面的VirtualAlloc函式保留了一段地址空間後,接下還你還可以繼續多次調用同樣的函式提交這段地址空間中的不同頁面。 |
MEM_RESET0x80000 | 表示,在所指定的記憶體範圍內的數據lpAddress的dwSize不再是利益。頁面不應該被讀出或寫入到分頁檔案。然而,將再次使用的記憶體塊後,所以它不應該decommitted的 。這個值不能使用任何其他的價值 。 使用這個值並不保證範圍與經營MEM_RESET將包含零。如果你想的範圍包含零,decommit記憶體,然後將它重新作出 。 當您指定MEM_RESET,VirtualAlloc函式忽略值flProtect。但是,您仍然必須設定flProtect有效的值,比如,PAGE_NOACCESS。 如果你使用MEM_RESET的記憶體範圍映射到一個檔案,VirtualAlloc返回一個錯誤。如果它被映射到分頁檔案共享視圖是唯一可以接受的的 。 |
分配類型 也可以是下列值
可能的數值 | 含義 |
---|---|
MEM_LARGE_PAGES0x20000000的 | 分配記憶體使用大頁面支持。 大小和對齊必須是一個大頁面的最低多個 。要獲得這個值,使用GetLargePageMinimum。 |
MEM_PHYSICAL0x400000 | 儲備的地址範圍,可用於記憶體地址視窗擴展(AWE)的頁面。 此值必須使用MEM_RESERVE,並沒有其他值。 |
MEM_TOP_DOWN0x100000 | 在儘可能高的地址分配記憶體。這可以比普通的分配速度較慢,尤其是當需要許多分配。 |
MEM_WRITE_WATCH0x200000 | 導致系統來跟蹤分配的地區,都寫在頁面 。如果指定此值,則還必須指定MEM_RESERVE。 要檢索的頁面是否寫入,因為該地區被分配或寫跟蹤狀態被重置地址,調用GetWriteWatch功能。要重置寫跟蹤狀態,調用GetWriteWatch或ResetWriteWatch。寫跟蹤功能仍然啟用,直到該地區被釋放。 |
訪問類型
PAGE_READONLY 0x02 | 該區域為唯讀。如果應用程式試圖訪問區域中的頁的時候,將會被拒絕訪問。 |
PAGE_EXECUTE 0x10 | 區域包含可被執行的代碼。試圖讀寫該區域的操作將被拒絕。 |
PAGE_EXECUTE_READ 0x20 | 區域包含可執行代碼,應用程式只能讀該區域。 |
PAGE_READWRITE 0x04 | 區域不可執行代碼,應用程式可以讀寫該區域。 |
PAGE_EXECUTE_READWRITE 0x40 | 區域可以執行代碼,應用程式可以讀寫該區域。 |
PAGE_GUARD 0x100 | 區域第一次被訪問時進入一個STATUS_GUARD_PAGE異常,這個標誌要和其他保護標誌合併使用,表明區域被第一次訪問的許可權 |
PAGE_NOACCESS 0x01 | 任何訪問該區域的操作將被拒絕 |
PAGE_NOCACHE 0x200 | RAM中的頁映射到該區域時將不會被微處理器快取(cached) |
注:PAGE_GUARD和PAGE_NOCHACHE標誌可以和其他標誌合併使用以進一步指定頁的特徵。PAGE_GUARD標誌指定了一個防護頁(guard page),即當一個頁被提交時會因第一次被訪問而產生一個one-shot異常,接著取得指定的訪問許可權。PAGE_NOCACHE防止當它映射到虛擬頁的時候被微處理器快取。這個標誌方便設備驅動使用直接記憶體訪問方式(DMA)來共享記憶體塊。
返回值
如果調用成功,返回分配的首地址,
調用失敗,返回NULL 你可以通過GetLastError函式來獲取錯誤信息
筆記
VirtualAlloc可以通過並行多次調用提交一個區域的部分或全部來保留一個大的記憶體區域。多重調用提交同一塊區域不會引起失敗。這使得一個應用程式保留記憶體後可以隨意提交將被寫的頁。當這種方式不在有效的時候,它會釋放應用程式通過檢測被保留頁的狀態看它是否在提交調用之前已經被提交