2011-02-25 100 views
2

如果我有一個指針指向堆中的特定內存地址。我想這相同指針指向另一個內存地址,我應該先指定delete指針嗎?但是,在這種情況下,我實際上刪除了指針還是僅僅打破了指針指向的引用(內存地址)?內存泄漏問題;刪除指針

換句話說,如果我一個指針,這是否意味着它不再存在?或者,它在那裏,但沒有指出它在哪裏?

+3

除了給出的答案,請注意,C++也有新的[]和delete []操作符,它們不僅僅分配/刪除一個對象,而是整個數組。這是該語言令人難以置信的愚蠢特徵,因爲它在忘記[]時很容易造成內存泄漏。到目前爲止,最好的解決方案是根本不會擺弄新的/刪除,而是使用智能指針類:http://en.wikipedia.org/wiki/Smart_pointer – Lundin 2011-02-25 10:22:24

回答

6

delete的語法有點誤導。當你寫

T* ptr = /* ... */ 
delete ptr; 

您是刪除變量ptr。相反,您正在刪除ptr指向的對象。 ptr的值保持不變,它仍然指向過去的位置,因此,如果不先重新分配它,應確保不要對其進行取消引用。

沒有要求您delete一個指針,然後再重新分配它。但是,你應該確保如果你要重新分配一個指針,導致你丟失了最後一個指向被指向的對象的引用(例如,如果這個指針是程序中它指向的唯一指針),那麼你應該delete它確保你不泄漏內存。

許多C++程序員用來簡化何時釋放內存的邏輯的一項技術是使用smart pointers,這些對象重載模擬指針所需的操作符,並且自動執行自定義代碼以幫助跟蹤資源。例如,新的C++ 0x標準將爲此提供shared_ptrunique_ptr類型。 shared_ptr就像一個普通的指針,除了它跟蹤一個資源有多少個shared_ptr。當資源的最後一個shared_ptr在其指向的位置(通過重新分配或被銷燬)發生更改時,它將釋放該資源。例如:

{ 
    shared_ptr<int> myPtr(new int); 
    *myPtr = 137; 
    { 
     shared_ptr<int> myOtherPtr = myPtr; 
     *myPtr = 42; 
    } 
} 

注意無處在此代碼是那裏delete打電話到呼叫匹配new!這是因爲shared_ptr足夠聰明,可以注意到最後一個指針停止指向資源的時間。

使用智能指針有幾個特性需要注意,但他們非常值得花時間學習。一旦你瞭解他們的工作方式,你就可以寫出更清晰的代碼。

1

當你delete一個指針,你釋放分配給內存指出對象。所以,如果你只是想讓你的指針指向一個新的內存位置,你應該是而不是delete指針。但是如果你想破壞它目前指向的對象,然後指向一個不同的對象,那麼你應該delete指針。

1

xtofl雖然很有趣,但有點正確。

如果您'新建'了一個內存地址,那麼您應該刪除它,否則請不要管它。也許你在想太多,但你會這樣想。是的,記憶永遠在那裏,但是如果你圍着它,你需要把圍欄放下,否則沒有其他人可以。

+0

我認爲這應該是最簡單的規則:一個新的==一個刪除。不要打擾更多。然而嘗試避免新聞;) – 2011-02-25 10:20:00

1

當您撥打delete時,您將指針指向的內存標記爲空閒 - 堆獲取它的所有權並可以重用它,這就是全部,the pointer itself is usually unchanged

如何處理指針取決於你想要的。如果您不再需要該內存塊 - 請使用delete釋放該塊。如果以後需要它 - 將地址存儲在某處,以便以後可以檢索。

1

總之,你不「刪除指針」,你刪除指針指向的任何東西。

這是一個古典問題:如果你刪除它,並且別人指向它,它們將讀取垃圾(並且很可能會導致應用程序崩潰)。另一方面,如果你不知道這是最後一個指針,你的應用程序將會泄漏內存。另外,指針可能指向最初不是由「新」分配的東西,例如,一個靜態變量,堆棧中的對象或另一個對象的中間。在所有這些情況下,您不允許刪除指針指向的任何內容。

通常,在設計應用程序時,您(是的,您)必須決定應用程序的哪個部分擁有特定的對象。它只有在它完成後才能刪除對象。

1

要直接回答你的問題,這已經被問過。 delete會刪除你的指針指向的內容,但是Bjarne Stroustrup提出了一個建議,指針本身的值不能再被依賴,特別是如果它是一個l值。如果你迭代指針,所有這些都被分配與new陣列

for(p = first; p != last; ++p) 
{ 
    delete p; 
} 

:但是這並不影響到其重新分配所以這將是有效的能力。

C++中的內存管理最好用稱爲RAII的技術「資源獲取是初始化」來完成。

這實際上意味着當你分配資源的時候,你立即關心它的生命週期,即你通過將它放入一個對象中來「管理」它,當它不再需要的時候將會刪除它。

shared_ptr是一種常用的技術,其中資源將在許多地方使用,並且您不確定哪些是最後一個「釋放」它,即不再需要它。

shared_ptr通常在其他地方僅用於其語義,也就是說您可以很容易地複製和分配它們。

還有其他內存管理智能指針,特別是std :: auto_ptr,它將被unique_ptr取代,還有scoped_ptr。 weak_ptr是一種能夠獲得shared_ptr的方法,如果某個地方存在shared_ptr,而不是自己持有引用。你可以調用「lock()」給你一個shared_ptr給內存,或者如果所有當前的共享指針都不存在,那麼它就是NULL。

對於數組,您通常不會使用智能指針,而只是使用矢量。

對於字符串,您通常會使用字符串類而不是將其視爲char的向量。