Win內存分配函數(GlobalAlloc/HeapAlloc/LocalAlloc/VirtualAlloc) 關於內存的5個函數(malloc,VirtualAlloc,GlobalAlloc,L

Win內存分配函數(GlobalAlloc/HeapAlloc/LocalAlloc/VirtualAlloc)html

來源:http://blog.csdn.net/chunyexiyu/article/details/39320805算法

內存分配函數/內存管理API

參考:編程

Windows MSDNwindows

http://msdn.microsoft.com/en-us/library/aa908768.aspx安全

 

附助資料:數據結構

http://blog.csdn.net/susubuhui/article/details/7315094less

http://wenku.baidu.com/link?url=yxgCWePPV1kFaIUciEspYgm34wNAnMLDoduBlfsEEo-mW0JFRVEOkixomUjPatqw_jOXZcqQ1CLoeBSZqLuse1KiyHD6ysZTMIzLy_sPgPS函數

http://blog.csdn.net/sharecode/article/details/7464915工具

 

Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu  轉載請標明來源 post

 

 

 

對於Windows來講,提供了一些API接口進行Heap內存管理,是獨立於C++/C程序以外的,僅用於Windows平臺的API。

 

大概分爲下面幾組接口:

 

老的Heap接口GlobalXXX(新程序不建議使用,這些函數存在主要是兼容之前寫的程序):

GlobalAlloc/GlobalRelloc/GlobalFree:從Heap申請一塊內存

GlobalLock/GlobalUnlock: 從GlobalAlloc的內存中申請一段內存

函數參數:

 

 

新的Heap接口HeapXXX:

HeapCreate/HeapDestroy/GetProcessHeap:從Heap中申請一塊內存

HeapAlloc/HeapRelloc/HeapFree/HeapSize:從HeapCreate的內存中申請一段內存

HeapValidatee:查詢Heap或Alloc的信息

 

當前進程Heap內存接口LocalXXX:

LocalAlloc/LocalReAlloc/LocalFree/LocalSize:從當前Heap的內存中申請一段內存,至關於從HeapAlloc從GetProcessHeap中申請內存。

 

虛擬地址內存接口: VirtualXXX

VirtualAlloc/VirtualFree/ VirtualProtect/VirtualQuery:從進程堆中申請頁面內存數據。一般用於申請一段大內存,最少申請一頁。reserves or commits a region of pages。

關於這一塊詳細請參考:http://blog.csdn.net/sharecode/article/details/7464915

 

malloc,new,VirtualAlloc,HeapAlloc這幾組的執行效率:

參考:http://blog.csdn.net/susubuhui/article/details/7315094

分配大內存的時候 VirtualAlloc才能體現出優點,申請小內存時比較慢。

至於小塊內存那就是HeapAlloc > malloc > new,由於都是調用HeapAlloc,直接使用HeapAlloc要快不少。

 

擴展的新接口xxxEx(不是全部版本都支持)

以Ex結尾,例如VitualAllocEx,能夠指定process handle,從而從其它運行進程空間申請一段內存。

 

函數說明:

HeapCreate:

從內存區申請一段內存做爲堆。This function reserves memory from the shared memory area.

HeapDestroy:

刪除HeapCreate建立的堆。This function destroys the specified heap object.

GetProcessHeap:

獲取當前進程的堆Handle。注意這個不能使用Destroy刪除。This function obtains a handle to the heap of the calling process. This handle can then be used in calls to the HeapAlloc,HeapReAlloc,HeapFree, andHeapSize functions.

 

HeapAlloc:

從指定堆申請一段內存,該段內存是不被移動的。This function allocates a block of memory from a heap. The allocated memory is not movable.

HeapReAlloc:

從指定堆從新申請一段內存。This function reallocates a block of memory from a heap. The allocated memory is not movable.

HeapFree:

釋入HeapAlloc或HeapReAlloc申請的內存。This function frees a memory block from a heap. The memory block was allocated by the HeapAlloc or theHeapReAllocfunction.

HeapSize:

根據Handle、內存開始地址,查詢一段HeapAlloc內存的大小。This function returns the size, in bytes, of a memory block allocated from a heap by the HeapAllocorHeapReAlloc function.

 

HeapValidate:

檢查Heap Handle或Heap Handle下申請的內存是否有效。

This function validates the specified heap. HeapValidate scans all the memory blocks in the heap and verifies that the heap control structures maintained by the heap manager are in a consistent state. The HeapValidate function can also be used to validate a single memory block within a specified heap without checking the validity of the entire heap.

 

LocalAlloc/LocalReAlloc/LocalFree/LocalSize:

從當前進程Heap中進行操做。該組函數至關於HeapXXX指定Heap Handle爲當前進程Handle。函數參考HeapAlloc / HeapReAlloc/ HeapFree/ HeapSize做用。

LocalAlloc : This function allocates the specified number of bytes from the heap.

In the linear Windows Embedded CE API environment, there is no difference between the local heap and the global heap.LocalAlloc is equivalent toHeapAlloc(GetProcessHeap, …).

 

VirtualAlloc/VirtualFree/ VirtualProtect/VirtualQuery:

從當前進程空間中申請頁面空間數據,最少申請一頁。

The VirtualAlloc function reserves or commits a region of pages in the virtual address space of the calling process. Memory allocated by this function is automatically initialized to zero, unless MEM_RESET is specified.

To allocate memory in the address space of another process, use theVirtualAllocEx function.

 

關於內存的5個函數(malloc,VirtualAlloc,GlobalAlloc,LocalAlloc,HeapAlloc)

來源:http://www.cnblogs.com/Madridspark/p/5778433.html

VirtualAlloc

  該函數的功能是在調用進程的虛地址空間,預約或者提交一部分頁,若是用於內存分配的話,而且分配類型未指定MEM_RESET,則系統將自動設置爲0

  一次分配 1PAGE 以上的 RAM. 每次分配都是 PAGE 的整數倍. 你不會想爲了分配 1 個 BYTE 的空間而浪費剩下的 4095 字節. OK, 你能夠本身寫算法, 多分配幾 PAGE. 而後每次分配少許數據時就從那幾 PAGE 中劃分出來. KERNEL32 提供了一個解決辦法, 用 HeapAlloc/GlobalAlloc 分配 RAM. 這樣, KERNEL32 幫助完成分配動做, 而且儘可能在減小用於跟蹤空閒區域和已佔用區域消耗的數據結構.

 

GlobalAlloc 和 LocalAlloc

  從全局堆中分配出內存供程序使用

   都是 Windows 系統提供的內存分配函數, 他們的區別在於 16BIT 代碼時代, 那時沒有不一樣的進程內存空間, GlobalAlloc 是在全局的, 公用的遠堆上分配; LocalAlloc 則在任務本身的近堆上分配. 在 Win32 平臺下這兩個函數是徹底相同的, 都是在進程本身的內存空間中分配, Lock 以後的結果是普通指針(32位近指針). 

 

HeapAlloc

  從堆上分配一塊內存,且分配的內存是不可移動的(即若是沒有連續的空間能知足分配的大小,程序不能將其餘零散的空間利用起來,從而致使分配失敗),該分配方法是從一指定地址開始分配,而不像GloabalAlloc是從全局堆上分配,這個有多是全局,也有多是局部。

  HeapCreate 就已經完成了建立堆的操做. HeapAlloc, HeapReAlloc 和 HeapFree 都是從這個堆中分配, 釋放內存的函數. 也就是說, Windows 系統其實已經爲咱們提供了完整的一套使用本身的局部堆的操做, 不過沒有看到指定分配策略的方法. 根據編譯器提供的源代碼來 看, VC 中的 malloc, realloc 和 free 等函數主要功能就是用這幾個 API 函數來實現的, 而 BC 中的實現至關複雜, 彷佛是維護了一套本身的邏輯. 聽說 BC 的內存分配比 VC 快, 大概是這個緣由. 

  好久之前也有個產品叫作 WINDOWS. 那時候的 WINDOWS 是 16BIT 的, 地址空間有些緊俏, 有錢不夠, 還須要糧票肉票才能拿到. 你已經調用 GlobalAlloc 和已經出錢的性質同樣. GlobalAlloc 還不夠, 有時候須要 GlocalLock 才能肯定你的東西確實能夠拿到手, 否則你的指針會非法, 被充公, 你的應用會被殺頭. 扯遠了. 後來 OS 進化了, 以爲能夠取消糧票肉票, 可是你必須用新版鈔票才行. 那就是 HeapAlloc. 只要市場上的 RAM 數量沒問題, 你的 HeapAlloc 沒問題, 那就總能拿到東西. 可是, 你總不能說有了 2000 版的鈔票, 那 80 版的立刻做廢啊, 那 GlobalAlloc 也只好繼續流通下去. 至於能夠流通到何時, 沒人知道.       // 這比喻至關經典啊!!!

  new 與它們的區別未免太大, 由於與 C++ 的構造函數和異常機制有關. 通常編譯器中的 new 都是用 malloc 來分配內存的. 用 malloc 與其它兩個函數比較應該更合理. 通常 malloc 的實現並非從系統的堆中分配的, 而是從編譯器鏈接的運行庫本身管理的堆中, 在 Win32 平臺上的開發工具的編譯結果中, 一般是用 HeapCreate 建立一個堆, 用 HeapAlloc 和 HeapRealloc 維護堆的空間增加, 在最後用 HeapDestroy 刪除堆. 而在用 malloc 分配, 用 free 釋放時則由運行庫的代碼負責從這個堆中分配空間和向這個堆中歸還空間, 並維護這個堆中的數據結構. 因爲 malloc 堆的管理是由運行庫本身管理的, 所在當咱們使用靜態運行庫時, 若是在一個 DLL 中用 malloc 分配了內存而在另外一個 DLL 中用 free 去釋放它, 一般都會產生問題. 這是由於每一個DLL都鏈接了一份運行庫的代碼, 從而也都有一個本身的局部堆, 而在用 free 釋放時它會假設這塊內存是在本身的堆中分配的, 從而致使錯誤. 而經過 GlobalAlloc 和 LocalAlloc 分配的內存不存在這個問題.

 

 

HeapAlloc、VirtualAlloc、GlobalAlloc和LocalAlloc 

來源:http://blog.chinaunix.net/uid-26111972-id-2239571.html

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中
LocalAlloc和GlobalAlloc是有區別的,由於在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 commitSIZE_T dwSize, // size of regionDWORD flAllocationType, // type of allocationDWORD 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指針。
相關文章
相關標籤/搜索