C++中delete與delete[]的問題

1.C++中delete之後指針指向問題

在C++中經常需要用new進行動態內存分配,然後使用delete或者delete[]進行內存的釋放。但是實際上delete並沒有刪除指針本身,而是標記指針指向的那塊內存區域可用,如果不講指針置爲空的話,便會造成一定的風險。例如:delete ptr;執行之後,ptr指針仍然存在,並且會隨機指向一個地址,如果後續程序仍然需要訪問ptr這個指針就會造成風險。

通過下面簡單的例子就可以看出來:

#include<iostream>

using namespace std;

 

void main()

{

int *ptr = new int;//爲ptr分配1個int的內存

*ptr = 5;

cout << "刪除指針前指針地址:" << ptr<<endl;

delete ptr;//刪除指針

cout << "刪除指針後指針地址:" << ptr << endl;

}

上面這個小例子足以說明這個問題,因此在書寫程序的時候應當注意將指針指向nullptr。

  1. C++中delete與delete[]的區別以及濫用造成的問題

C++中提供delete和delete[]兩種方式對內存進行釋放,但他們只能釋放new動態分配的內存。這兩種方式分別適用於不同的情況,delete是對指向單個元素或者對象的指針進行釋放,如上1中所示。而delete[]是對數組或者對象數組進行內存的釋放,例如:

Int *ptr=new int[4];//分配4個int型內存空間

delete[] ptr;//釋放該空間

對於普通數組型的內存釋放,使用delete和delete[]他們沒有多大區別,因爲它們直接將分配的內存塊標記成可用。但是對於對象數組錯誤的使用delete和delete[]便會出現一些問題。

第一種情況:對單個對象使用delete進行內存釋放

例如:

#include<iostream>

using namespace std;

 

class Test{

public:

~Test() { cout << "調用析構函數" << endl; }

};

 

void main()

{

Test *ptr=new Test;//分配一個對象長度的內存

delete[] ptr;//用delete[]釋放該內存

}

在上面的簡短例子中,建立了一個Test類用於測試,其中僅僅有一個析構函數。然後用new分配了一個Test類對象的空間,再用delete[]對內存進行釋放,此時會出現無限次調用析構函數的情況。造成這個問題的原因是什麼呢?首先我們從使用new對對象數組進行內存分配方式說起。

例如:Test *ptr=new Test[10];//使用new分配10個Test對象長度的內存

實際上執行的時候是new[](10*sizeof(Test)+4),即分配了(10*sizeof(Test)+4)長度的內存空間,多處的4個字節用於存儲10這個數字,在對對象數組進行析構的時候便知道調用析構函數的次數。而當使用delete[]對單個對象進行釋放時,編譯器認爲刪除的時一個對象數組,便會訪問Test分配內存空間的後面4個字節,來知道進行析構的次數。然而後面四個字節並不是一個賦予了的值而是一個隨機值,所以就出現了無限析構的錯誤。那麼具體析構多少次呢?這就要由那四個字節中的垃圾數據來決定了。

第二中種情況:使用delete對對象數組進行釋放

#include<iostream>

using namespace std;

 

class Test{

public:

~Test() { cout << "調用析構函數" << endl; }

};

 

void main()

{

Test *ptr=new Test[4];//分配4個對象長度的內存

delete ptr;//用delete釋放該內存

}

在上例中用new分配了四個Test對象長度的對象數組,然後使用delete對指針ptr進行釋放。最後的運行結果如圖所示,本來四個對象應當進行四次析構,但是實際上只執行了一次析構。這是因爲使用delete時,編譯器默認其爲單個對象,因此便只調用了一次析構函數,這樣就造成了剩下的對象空間並未釋放,造成了隱患。

  1. 總結

這是在學習C++中遇到的比較困惑的一個問題,這裏寫一個小的總結,使自己印象更深刻。不能夠錯誤的使用delete和delete[],並且在使用之後記得對指針進行置空處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章