直接看下面這道題:
使用 char* p = new char[10]申請一段記憶體,然後使用delete p釋放,有什麼問題?
a:會有記憶體洩露
b:不會有記憶體洩露,但不建議用
c:編譯就會報錯,必須使用delete p;
d:編譯沒問題,執行會直接崩潰
這道題題目開闢的是10個char型別的空間,因為是內建型別,析構時不會呼叫析構函式,所以並不會產生記憶體洩漏的問題,故而選擇b。
但是從好的程式設計習慣和語法上來講,這樣使用無疑是給自己找坑呢。
那麼現在拋開這道題來講,如果開闢的是自定義型別呢。
先看下面這段**:
class a
;int main()
這段**是可以通過編譯的。
那麼如果我在a類中顯式的給出析構函式呢?
這時候程式直接就崩掉了,想象為什麼。
new在開闢空間的時候會多開闢四個位元組來儲存析構的次數。
如果沒有顯式給出析構函式,編譯器自己做了優化,所以沒有報錯,而一旦你顯式給出析構函式嗎,系統便直接崩潰了,先來**崩潰的緣由。
如圖所示,如果用new出來的位元組,在析構的時候它會將指標調整到最開始開闢空間的位置,將多開闢的四個位元組也刪除了。
就像上面的**示例,開闢空間的時候從1的位置開始,呼叫delete析構卻從2的位置開始釋放,當然,這就是程式崩潰的原因,因為開始析構的位址不對。
僅是為了理解這部分,來試著給指標減去四個位元組,讓它從正確的位址開始析構,這時候,編譯成功通過了。
**如下,我們看下結果。
通過調整指標指向,讓程式確實可以正確的通過編譯且進行析構,但是因為前四個位元組沒有儲存開闢陣列的個樹,所以導致只呼叫了一次析構。
正確的使用delete來析構的話,這裡是會呼叫十次析構函式的。
所有在平時的學習和使用中一定要注意這些問題,對於new/new和delete/delete一定要配對使用。防止造成記憶體洩漏。
delete釋放new 造成的洩漏
正常 class ctest private int m value int main return 0 對應的彙編 while 1 對於new,vs2008是在申請記憶體的時候多申請了4個位元組大小的記憶體,用來存放陣列個數,返回給上層使用的是實際位址 4。錯誤的delete class ctes...
New動態分配 Delete 釋放記憶體
在c 中,對於變數和物件都是編譯器在編譯時分配好的,對於陣列初始化時,無法確定多少記憶體,很容意造成大開小用的情況。new 動態分配 一般格式 1.指標變數名 new 型別識別符號 2.指標變數名 new 型別識別符號 初始值 3.指標變數名 new 型別識別符號 記憶體單元個數 開闢陣列的定義方法...
記憶體的動態開闢與釋放
malloc free與new delete 1 new會拋異常,但是malloc不會拋異常 2 new delete屬於操作符,但是malloc free屬於函式 3 new申請空間的時候會呼叫建構函式進行初始化,malloc不會 delete釋放記憶體時會呼叫析構函式,free只是切斷了指向關係...