VC常用記憶體配置函數HeapAlloc,GlobalAlloc,LocalAlloc,VirtualAlloc,Malloc,New的異同

來源:互聯網
上載者:User

 

1. 首先我們來看HeapAlloc:
MSDN上的解釋為:HeapALloc是從堆上分配一塊記憶體,且分配的記憶體是不可移動的(即如果沒有連續的空間能滿足分配的大小,程式不能將其他零散的 空間利用起來,從而導致分配失敗),該分配方法是從一指定地址開始分配,而不像GloabalAlloc是從全域堆上分配,這個有可能是全域,也有可能是 局部。函數原型為:
LPVOID
HeapAlloc(
    HANDLE hHeap,
    DWORD dwFlags,
   SIZE_T dwBytes
    );
hHeap是進程堆記憶體開始位置。
dwFlags是分配堆記憶體的標誌。包括HEAP_ZERO_MEMORY,即使分配的空間清零。
dwBytes是分配堆記憶體的大小。
其對應的釋放空間函數為HeapFree。
2. 再看GlobalAlloc:該函數用於從全域堆中分配出記憶體供程式使用,函數原型為:
HGLOBAL GlobalAlloc(
UINT uFlags,
SIZE_T dwBytes
);
uFlags參數含義
GHND   GMEM_MOVEABLE和GMEM_ZEROINIT的組合
GMEM_FIXED   分配固定記憶體,傳回值是一個指標
GMEM_MOVEABLE   分配活動記憶體,在Win32中,記憶體塊不能在實體記憶體中移動,但能在預設的堆中移動。傳回值是記憶體對象的控制代碼,用函數GlobalLock可將控制代碼轉化為指標
GMEM_ZEROINIT   將記憶體內容初始化為零
GPTR   GMEM_FIXED和GMEM_ZEROINIT的組合
一般情況下我們在編程的時候,給應用程式分配的記憶體都是可以移動的或者是可以丟棄的,這樣能使有限的記憶體資源充分利用,所以,在某一個時候我們分配的那塊 記憶體的地址是不確定的,因為他是可以移動的,所以得先鎖定那塊記憶體塊,這兒應用程式需要調用API函數GlobalLock函數來鎖定控制代碼。如下: lpMem=GlobalLock(hMem); 這樣應用程式才能存取這塊記憶體。所以我們在使用GlobalAllock時,通常搭配使用GlobalLock,當然在不使用記憶體時,一定記得使用 GlobalUnlock,否則被鎖定的記憶體塊一直不能被其他變數使用。
GlobalAlloc對應的釋放空間的函數為GlobalFree。
3. LocalAlloc:該函數用於從局部堆中分配記憶體供程式使用,函數原型為:
HLOCAL LocalAlloc(
UINT uFlags,
SIZE_T uBytes
);
參數同GlobalAlloc。
在16位Windows中是有區別的,因為在16位windows用一個全域堆和局部堆來管理記憶體,每一個應用程式或dll裝入記憶體時,程式碼片段被裝入全域 堆,而系統又為每個執行個體從全域堆中分配了一個64kb的資料區段作為該執行個體的局部堆,用來存放應用程式的堆棧和所有全域或靜態變數。而 LocalAlloc/GlobalAlloc就是分別用於在局部堆或全域堆中分配記憶體。
由於每個進程的局部堆很小,所以在局部堆中分配記憶體會受到空間的限制。但這個堆是每個進程私人的,相對而言分配資料較安全,資料訪問出錯不至於影響到整個系統。
而在全域堆中分配的記憶體是為各個進程共用的,每個進程只要擁有這個記憶體塊的控制代碼都可以訪問這塊記憶體,但是每個全域記憶體空間需要額外的記憶體開銷,造成分配浪費。而且一旦發生嚴重錯誤,可能會影響到整個系統的穩定。
不過在Win32中,每個進程都只擁有一個省缺的私人堆,它只能被當前進程訪問。應用程式也不可能直接存取系統記憶體。所以在Win32中全域堆和局部堆都 指向進程的省缺堆。用LocalAlloc/GlobalAlloc分配記憶體沒有任何區別。甚至LocalAlloc分配的記憶體可以被 GlobalFree釋放掉。所以在Win32下編程,無需注意Local和Global的區別,一般的記憶體配置都等效於 HeapAlloc(GetProcessHeap(),...)。
LocalAlloc對應的釋放函數為LockFree。
4. VirtualAlloc:該函數的功能是在調用進程的虛地址空間,預定或者提交一部分頁,如果用於記憶體配置的話,並且配置類型未指定MEM_RESET,則系統將自動化佈建為0;其函數原型:
LPVOID VirtualAlloc(
LPVOID lpAddress, // region to reserve or commit
SIZE_T dwSize, // size of region
DWORD flAllocationType, // type of allocation
DWORD flProtect // type of access protection
);
VirtualAlloc可以通過並行多次調用提交一個地區的部分或全部來保留一個大的記憶體地區。多重調用提交同一塊地區不會引起失敗。這使得一個應用程 序保留記憶體後可以隨意提交將被寫的頁。當這種方式不在有效時候,它會釋放應用程式通過檢測被保留頁的狀態看它是否在提交調用之前已經被提交。
VirtualAlloc對應的釋放函數為VirtualFree。
5.Malloc:malloc與free是C++/C語言的標準庫函數,可用於申請動態記憶體和釋放記憶體。對於非內部資料類型的對象而言,光用 malloc/free無法滿足動態對象的要求。對象在建立的同時要自動執行建構函式,對象在消亡之前要自動執行解構函式。由於malloc/free是 庫函數而不是運算子,不在編譯器控制許可權之內,不能夠把執行建構函式和解構函式的任務強加於malloc/free。
6.New:new/delete是C++的運算子。可用於申請動態記憶體和釋放記憶體。C++語言需要一個能完成動態記憶體分配和初始化工作的運算子new, 以一個能完成清理與釋放記憶體工作的運算子delete。注意new/delete不是庫函數。C++程式經常要調用C函數,而C程式只能用malloc /free管理動態記憶體。new 是個操作符,和什麼"+","-","="...有一樣的地位.
        malloc是個分配記憶體的函數,供你調用的.
        new是保留字,不需要標頭檔支援.
        malloc需要標頭檔庫函數支援.new 建立的是一個對象,
        malloc分配的是一塊記憶體.
        new建立的對象你可以把它當成一個普通的對象,用成員函數訪問,不要直接存取它的地址空間
        malloc分配的是一塊記憶體地區,就用指標訪問好了,而且還可以在裡面移動指標.
記憶體流失對於malloc或者new都可以檢查出來的,區別在於new可以指明是那個檔案的那一行,而malloc沒有這些資訊。new可以認為是malloc加建構函式的執行。new出來的指標是直接帶類型資訊的。而malloc返回的都是void指標。
2009-08-04 17:17:34

來源:——http://hi.baidu.com/netspirit/blog/item/c033012c4a26e6e58b139987.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.