我有一個小功課問題。
下面的代碼給出:將值分配給已刪除的對象
int * p;
p = new int;
*p = 5;
的問題是:爲什麼沒用做
p = 0;
delete p;
但有用做
delete p;
p = 0;
?
在我看來,兩者都是無用的。如果一個對象被刪除,則不能分配新的值。
我也在這兩種情況下得到一個Segmentation fault
。
我有一個小功課問題。
下面的代碼給出:將值分配給已刪除的對象
int * p;
p = new int;
*p = 5;
的問題是:爲什麼沒用做
p = 0;
delete p;
但有用做
delete p;
p = 0;
?
在我看來,兩者都是無用的。如果一個對象被刪除,則不能分配新的值。
我也在這兩種情況下得到一個Segmentation fault
。
爲什麼它是以下有用的:
delete p;
p = 0;
從Stroustrup的回答引用:Why doesn't delete zero out its operand?
考慮
delete p; // ... delete p;
如果......部分不接觸然後第二個「刪除p」是一個嚴重的錯誤,即C++實現不能有效地保護自己免受(沒有不尋常的預防措施)。 由於根據定義刪除零指針是無害的,因此一個簡單的解決方案是「delete p;」做一個「p = 0;」在完成了其他所需的任何事情之後。但是,C++並不能保證這一點。 其中一個原因是delete的操作數不必是左值。考慮:
delete p+1; delete f(x);
這裏,刪除的實現沒有指向它可以分配零的指針。這些例子可能是罕見的,但他們暗示,這是不可能保證
any pointer to a deleted object is 0.'' A simpler way of bypassing that
規則'是有兩個指向的對象:T* p = new T; T* q = p; delete p; delete q; // ouch!
C++明確允許的刪除實現零出左值操作數,我曾希望實現能夠這樣做,但是這個想法似乎並未在實現者中流行起來。 如果考慮歸零指針重要,可以考慮使用破壞功能:
template<class T> inline void destroy(T*& p) { delete p; p = 0; }
考慮這個尚未另一個原因,儘量減少明確使用新的和依靠標準庫中的容器,處理刪除,等
注意,通過指針爲基準(以允許zero'd出指針)具有防止破壞()被調用用於一個右值的附加益處:
int* f(); int* p; // ... destroy(f()); // error: trying to pass an rvalue by non-const reference destroy(p+1); // error: trying to pass an rvalue by non-const reference
這將指針設置爲null,然後調用刪除:
p = 0;
delete p;
這好像是說
delete 0;
我想你所想的是,它被設置int值p指向歸零,但這樣做是這樣的:
*p = 0;
回想一下,刪除0
是允許的。因此,當你這樣做
p = 0;
delete p; // Deleting zero is ignored
你扔掉的p
(從而開創了內存泄漏)舊值,然後調用delete 0
,其中被忽略。
當你做到這一點,但是
delete p;
p = 0;
您使用舊值第一(解除分配的int
),才把零出來。這是有道理的,因爲只要執行delete
,p
的舊值就變得無用且危險。
雖然C++編譯器會在您嘗試刪除它時忽略零值指針,也就是說會編譯時沒有錯誤。但是,這在運行時肯定會導致seg故障。 – Ozraptor 2013-04-29 02:55:09
@Ozraptor不符合標準:允許「刪除0」和「空閒(NULL)」。這是一個正在運行的示例:[link](http://ideone.com/1PNXrt)。 – dasblinkenlight 2013-04-29 02:57:28
@Ozraptor:標準明確允許:第5.3.5節第2段 – 2013-04-29 02:58:35
在第一種情況下,您將POINTER p的值分配爲'0',而不是p指向的int值。這就是爲什麼它是無用的(實際上會導致內存泄漏),並且當您嘗試從內存地址'0'中刪除時導致seg故障。編輯 - 實際上我剛剛瞭解到段錯誤並不是由'刪除0'引起的,而'刪除0'是根據標準忽略的,所以其他的事情正在造成這種情況。
在第二種情況下你正在釋放內存/對象指向的P(這應該是細),然後分配指針具有值「0」,這也應該是好了,所以不知道爲什麼你在那裏發生seg斷層?在實用性方面,過去認爲將free'd指針設置爲null或'0'值是一種很好的做法,因此您可以在取消引用它們之前對其進行測試。
p = NULL;
和
p = 0;
在你的指針,而不是它所指向的對象分配值的上述情況。
是一樣的。刪除函數用於釋放動態分配給對象的內存。
當你說
delete p;
p = 0;
這好像是說免費分配給指針p 然後你說指針賦值爲NULL內存。哪個是對的。
在其他情況下,當你做到這一點
p = 0;
delete p;
你是說分配指針第一爲NULL。現在指針p 未指向任何有效的動態分配的內存。所以後來 當你說delete p時,編譯器找不到任何內存來釋放 ,並因此引發分段錯誤。
如果'delete p; p = 0;'給你一個段錯誤,你做錯了什麼。 – huskerchad 2013-04-29 02:51:00
我嘗試之後返回'p'的值。 – user1170330 2013-04-29 02:52:05
好吧,你去。 – huskerchad 2013-04-29 02:58:28