2013-07-07 140 views
3

爲了什麼我需要使用VirtualAlloc/VirtualAllocEx?我需要什麼來使用VirtualAlloc/VirtualAllocEx?

一個例子,我發現的一個案例 - 如果我分配了4 GB的虛擬內存,那麼如果我沒有使用它們全部,那麼我不花費物理內存,如果我調整我的陣列大小,我會不需要將新數據重新分配和複製到新陣列。

struct T_custom_allocator; // which using VirtualAllocEx() 
std::vector<int, T_custom_allocator> vec; 
vec.reserve(4*1024*1024*1024); // allocated virtual memory (physical memory is not used) 
vec.resize(16384); // allocated 16KB of physical memory 
// ... 
vec.resize(32768); // allocated 32KB of physical memory 
        // (no need to copy of first 16 KB of data) 

如果我使用的標準分配,我需要數據的拷貝,當我做調整:

std::vector<int> vec; 
vec.resize(16384); // allocated 16KB of physical memory 
// ... 
vec.resize(32768); // allocated 32KB of physical memory 
        // and need to copy of first 16 KB of data 

或用standatd分配器,我必須花4GB的物理內存

std::vector<int> vec; 
vec.reserve(4*1024*1024*1024); // allocated 4GB of physical memory 
vec.resize(16384); // no need to do, except changing a local variable of size 
// ... 
vec.resize(32768); // no need to do, except changing a local variable of size 

但是,爲什麼這比realloc()更好? http://www.cplusplus.com/reference/cstdlib/realloc/

是否有任何其他情況下使用VirtualAlloc [Ex]帶來的好處?

回答

11

另一種用於VirtualAllocEx的尚未提及的用途是在另一個進程的地址空間中分配內存。請注意,第一個參數是進程的句柄 - 該函數在該進程的虛擬地址空間內分配內存。

我在將代碼注入另一個進程時,通過在目標進程中強制執行LoadLibrary調用,我使用過此代碼。基本步驟如下:

  1. 獲取目標進程的進程ID(例如,具有類似GetWindowThreadProcessId)。
  2. 使用OpenProcess以適當的權限獲取進程的句柄。
  3. 使用VirtualAllocEx在該進程中分配一些內存。
  4. 將您的DLL的名稱複製到該內存中,並使用WriteProcessMemory
  5. 使用GetProcAddress獲取LoadLibrary函數的地址。
  6. 致電CreateRemoteThread在目標進程中啓動LoadLibrary調用,其中線程參數是您用VirtualAllocEx(包含DLL的名稱)分配的內存。

不是你需要知道所有這些,但我雖然是一個有趣的用例。

5

VirtualAlloc和非常簡單的術語VirtualAllocEx分配生的網頁,與所有其他存儲功能從mallocGlobalAlloc都使用VirtualAllocEx下方。 VirtualAlloc的問題在於它基本上是原始記憶,沒有可用的重新分配或重新定位。因此,如果你的地址空間變得分散,你就沒有辦法,只能釋放和重建。

主要用例VirtualAlloc是當你需要編寫自己的內存管理器,用於說SQL實現在那裏可以產生巨大的變化。或者,如果您正在實施即時編譯器(JIT),則需要能夠將您編譯的頁面上的保護標誌從讀/寫更改爲讀/執行,以不觸發Data Execution Prevention。

相關問題