new和delete的原理
當我們在程式中寫下 new 和 delete 時,我們實際上呼叫的是 c++ 語言內建的 new operator 和 delete operator.所謂語言內建就是說我們不能更改其含義,它的功能總是一致的。以 new operator 為例,它總是先分配足夠的記憶體,而後再呼叫相應的型別的建構函式初始化該記憶體。而 delete operator 總是先呼叫該型別的析構函式,而後釋放記憶體(圖1)。我們能夠施加影響力的事實上就是 new operator 和 delete operator 執行過程中分配和釋放記憶體的方法。
new operator 為分配記憶體所呼叫的函式名字是 operator new,其通常的形式是 void * operator new(size_t size); 其返回值型別是 void*,因為這個函式返回乙個未經處理(raw)的指標,未初始化的記憶體。引數 size 確定分配多少記憶體,你能增加額外的引數過載函式 operator new,但是第乙個引數型別必須是 size_t.
delete operator 為釋放記憶體所呼叫的函式名字是 operator delete,其通常的形式是 void operator delete(void *memorytobedeallocated);它釋放傳入的引數所指向的一片記憶體區。
這裡有乙個問題,就是當我們呼叫 new operator 分配記憶體時,有乙個 size 引數表明需要分配多大的記憶體。但是當呼叫 delete operator 時,卻沒有類似的引數,那麼 delete operator 如何能夠知道需要釋放該指標指向的記憶體塊的大小呢?答案是:對於系統自有的資料型別,語言本身就能區分記憶體塊的大小,而對於自定義資料型別(如我們自定義的類),則 operator new 和 operator delete 之間需要互相傳遞資訊。
當我們使用 operator new 為乙個自定義型別物件分配記憶體時,實際上我們得到的記憶體要比實際物件的記憶體大一些,這些記憶體除了要儲存物件資料外,還需要記錄這片記憶體的大小,此方法稱為 cookie.這一點上的實現依據不同的編譯器不同。(例如 mfc 選擇在所分配記憶體的頭部儲存物件實際資料,而後面的部分儲存邊界標誌和記憶體大小資訊。g++ 則採用在所分配記憶體的頭 4 個自己儲存相關資訊,而後面的記憶體儲存物件實際資料。)當我們使用 delete operator 進行記憶體釋放操作時,delete operator 就可以根據這些資訊正確的釋放指標所指向的記憶體塊。
以上論述的是對於單個物件的記憶體分配/釋放,當我們為陣列分配/釋放記憶體時,雖然我們仍然使用 new operator 和 delete operator,但是其內部行為卻有不同:new operator 呼叫了operator new 的陣列版的兄弟- operator new,而後針對每乙個陣列成員呼叫建構函式。而 delete operator 先對每乙個陣列成員呼叫析構函式,而後呼叫 operator delete 來釋放記憶體。需要注意的是,當我們建立或釋放由自定義資料型別所構成的陣列時,編譯器為了能夠標識出在 operator delete 中所需釋放的記憶體塊的大小,也使用了編譯器相關的 cookie 技術。 (千萬要注意,使用了編譯相關的cookie技術,我可是吃過虧的人了阿)
綜上所述,如果我們想檢測記憶體洩漏,就必須對程式中的記憶體分配和釋放情況進行記錄和分析,也就是說我們需要過載 operator new/operator new;operator delete/operator delete 四個全域性函式,以截獲我們所需檢驗的記憶體操作資訊。
new 和delete的實現
通過了解發現,原來在new的內部實現中只涉及記憶體的分配,也就是只考慮malloc的使用,而關於呼叫建構函式的部分則是交由編譯器處理,所以這裡看不到呼叫建構函式的 由malloc分配記憶體空間,然後判斷是否分配,並發出bad alloc的異常訊息.如果分配成功,返回指向記憶體的指標,否則。返回nul...
new和delete的使用
一 基本資料型別的動態分配 new和delete已經完全包含malloc和free的功能,並且更強大 方便 安全。使用動態分配記憶體時不能忘記釋放記憶體,不要忘記出錯處理!下面先看new和delete的基本使用方法。includeusing namespacestd intmain 釋放記憶體del...
new和delete的用法(摘自)
對於計算機程式設計而言,變數和物件在記憶體中的分配都是編譯器在編譯程式時安排好的,這帶來了極大的不便,如陣列必須大開小用,指標必須指向乙個已經存在的變數或物件。對於不能確定需要占用多少記憶體的情況,動態記憶體分配解決了這個問題。new和delete運算子是用於動態分配和撤銷記憶體的運算子。一 new...