最近在找工作,好煩啊!!!!!!!!
算了,與其一直鬱悶,不如先做點筆記,換換腦子(還是學東西有意思!)。
參考部落格:
http://blog.csdn.net/fgh_555/article/details/2560774
http://hi.baidu.com/gamedot/item/0727f36eb4fa65116995e6d8
1. HeapAlloc: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參數含義
GMEM_FIXED 分配固定記憶體,傳回值是一個指標
GMEM_MOVEABLE 分配活動記憶體,在Win32中,記憶體塊不能在實體記憶體中移動,但能在預設的堆中移動。傳回值是記憶體對象的控制代碼,用函數GlobalLock可將控制代碼轉化為指標
GMEM_ZEROINIT 將記憶體內容初始化為零
GPTR GMEM_FIXED和GMEM_ZEROINIT的組合
GHND GMEM_MOVEABLE和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。
GlobalAlloc和LocalAlloc都是Windows系統提供的記憶體配置函數,他們的區別源於16位代碼時代,那時沒有不同的進程記憶體空間,GlobalAlloc是在全域的、公用的遠堆上分配,LocalAlloc則在任務自己的近堆上分配。在Win32平台下這兩個函數是完全相同的,都是在進程自己的記憶體空間中分配,Lock之後的結果是普通指標(32位近指標)。
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的實現並不是從系統的堆中分配的,而是從編譯器串連的運行庫自己管理的堆中分配。在Win32平台上的開發工具的編譯結果中,通常是用HeapCreate建立一個堆,用HeapAlloc和HeapRealloc維護堆的空間增長,在最後用HeapDestroy刪除堆。而在用malloc分配、用free釋放時則由運行庫的代碼負責從這個堆中分配空間和向這個堆中歸還空間,並維護這個堆中的資料結構。
由於malloc堆的管理是由運行庫自己管理的,所以當我們使用靜態運行庫時,如果在一個DLL中用malloc分配了記憶體而在另一個DLL中用 free去釋放它,通常都會產生問題,這是因為每個DLL都串連了一份運行庫的代碼,從而也都有一個自己的局部堆,而在用free釋放時它會假設這塊記憶體是在自己的堆中分配的,從而導致錯誤。而通過GlobalAlloc和LocalAlloc分配的記憶體不存在這個問題。
HeapCreate完成了建立堆的操作,HeapAlloc、HeapRealloc和HeapFree都是從這個堆中分配、釋放記憶體的函數。也就是說,Windows系統其實已經為我們提供了完整的一套使用自己的局部堆的操作,不過沒有看到指定分配策略的方法。根據編譯器提供的原始碼來看,VC中的malloc、realloc和free等函數主要功能就是用這幾個API函數來實現的,而BC中的實現相當複雜,似乎是維護了一套自己的邏 輯。據說BC的記憶體配置比VC快,大概就是這個原因了。
malloc對應的釋放函數為free。
6. New:是C++的運算子,主要用來建立類,與C++的建構函式和異常機制有關,與上述其它函數的使用環境大相庭徑。一般編譯器中的new都是用malloc來分配記憶體的。
New對應的釋放函數為delete。