不要輕易delete void*指針,這樣會隱藏比較多的錯誤。


 1 #include<iostream>
 2 using namespace std;
 3 
 4 class Object{
 5     void* data;
 6     const int size;
 7     const char id;
 8 public:
 9     Object(int sz, char c) :size(sz),id(c){
10         data = new char[size];
11         cout << "Constructor Object" << id << ",size=" << size << endl;
12     }
13     ~Object(){
14         cout << "Destructing object" << id << endl;
15         delete[]data;
16     }
17     
18 };
19 
20 int main(){
21     Object* a = new Object(40,'a');
22     delete a;
23     void* b = new Object(41,'b');//會調用構造函數
24     delete b;//不會調用析構函數
25 
26          return 0;

}

首先我們來開一下這個類的內存模型。

 

在運行結果截圖中,我們看到

Object* a = new Object(40,'a');
delete a;
可以正確的構造對象,在析構函數中也可以把用delete把data指針指向的內存釋放掉。(在對void*類型的內存使用delete,並不會發生錯誤,僅僅是把內存釋放掉。)但是在main函數中,我們看到delete知道它所操作的對象的類型是十分重要的。我們看到
void* b = new Object(41,'b');//會調用構造函數
   delete b;//不會調用析構函數
在用delete刪除b的操作中,我們只是對b指向的對象進行了釋放,並沒有調用構造函數,也就是說data指向的內存並沒有被釋放,而此時又沒有指針指向剛才data指針指向的內存,從而造成了內存的丟失,更會造成內存的泄露。


這會有一個比較有意思的地方就是如果寫下面的代碼,
Object* pc=(Object*)malloc(sizeof(Object));//這個事情我們在new delete運算符與malloc free庫函數的區別中講到過,這時候不會調用構造函數,只會分配內存
delete pc;//而這句話因為pc是有類型的,不是void*所以會調用析構函數


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM