p所指的空間。
好比 int* p = new int(1);
delete p;
就會在堆上分配一塊內存,看成int類型使用,並賦值爲1,將其地址儲存在棧上的int*類型的p裏。delete p會釋放p所指向的內存。而這裏p爲一自動變量,其自己在程序退出其做用域時銷燬。
用delete命令處理某個指針,說是把那個指針刪除了是不正確的。程序員
delete命令指示釋放了那個指針本來所指的那部份內存而已。被delete後的指針p的值(地址值)並不是就是NULL,而是隨機值。安全
也就是被delete後,若是再也不加上一句p=NULL,p就成了「野指針」,在內存裏亂指一通。函數
若是在定義p的那個函數在delete了p後,沒再調用p,就沒什麼問題,在這個函數結束後,p就會跟其它變量同樣被消除。但若在那個函數裏delete了p後,又沒再給p賦值(地址值),再次調用p就危險了,由於這時p在內存裏亂指,有可能指到一些重要地址,隨時可能系統崩潰。指針
//p=NULL是個好習慣
//就像你蹲完廁所要洗手同樣
《問題》危險的代碼:內存
int* p=new int(1);
delete p;
delete p;作用域
探討一:編譯器
連續兩次對同一個指針delete ,會形成嚴重的錯誤。編譯器會檢測出這樣的錯誤嗎?或許一些編譯器會的,但別太過期望編譯器。編譯
探討二:class
第一次delete後,p自動爲空(NULL)了嗎?不是的。變量
探討三:
在delete以前會自動檢查p是否爲空(NULL),若是爲空(NULL)就再也不delete了嗎?確實是如此。
探討四:
刪除爲空(NULL)的指針是不會有任何問題的嗎?確實是如此。
探討五:
#define SAFE_DELETE(p) delete (p); p = 0;
這樣就就萬事大吉了嗎?好像不是的。
delete p+1;//在C++中是正確的
SAFE_DELETE(p+1)將會致使錯誤
探討六:
沒有好的方法解決重複釋放這樣的問題,只能靠程序員的細心了。
《結論》安全的代碼:
int* p=new int(1);
delete p;
p = NULL;
(1)delete 一次之後,p成了野指針,它做爲地址的值仍是有效地沒還能夠訪問它之前指向的內存,不過那片內存被從新格式化了;(2)p不等於NULL,用 if(p) 語句不能判斷它指向的內存是否有效(此時它指向的內存無效,p自己有效);(3)delete 一次之後,不能再次delete,不然會報錯;(4)此時若是誤用p指針,仍然能夠修改內存的值和從該處取出數值,但此時數據不受保護,該內存空間可能被從新被分配給別的變量;(5)若是p指向的空間再次被new函數分配,即便是分配給別的指針,即便分配大小與原來不同,p又恢復了效力,能夠改變內存的值,甚至能夠從新被delete,p的做用與新分配的指針同樣;