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 分配的內存不存在這個問題.
Malloc
malloc 與free是C++/C語言的標准庫函數,可用於申請動態內存和釋放內存。對於非內部數據類型的對象而言,光用 malloc/free無法滿足動態對象的要求。對象在創建的同時要自動執行構造函數,對象在消亡之前要自動執行析構函數。由於malloc/free是庫函數而不是運算符,不在編譯器控制權限之內,不能夠把執行構造函數和析構函數的任務強加於malloc/free。
New
new/delete 是C++的運算符。可用於申請動態內存和釋放內存。C++語言需要一個能完成動態內存分配和初始化工作的運算符new,以一個能完成清理與釋放內存工作的運算符delete。注意new/delete不是庫函數。C++程序經常要調用C函數,而C程序只能用malloc /free管理動態內存。new 是個操作符,和什么"+","-","="...有一樣的地位.
malloc是個分配內存的函數,供你調用的.
new是保留字,不需要頭文件支持.
malloc需要頭文件庫函數支持.new 建立的是一個對象,
malloc分配的是一塊內存.
new建立的對象你可以把它當成一個普通的對象,用成員函數訪問,不要直接訪問它的地址空間
malloc分配的是一塊內存區域,就用指針訪問好了,而且還可以在里面移動指針.
new如果分配失敗的話絕不會返回一個空指針NULL,而是會拋出失敗異常
內存泄漏對於malloc或者new都可以檢查出來的,區別在於new可以指明是那個文件的那一行,而malloc沒有這些信息。new可以認為是malloc加構造函數的執行。new出來的指針是直接帶類型信息的。而malloc返回的都是void指針。
還沒有完全理解透,還需要再完整地看完一本操作系統的書。