New和delete的原理

2021-05-28 12:16:04 字數 1866 閱讀 6599

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...