2010-06-08 113 views
6

我有一個包含指針一個結構:C++:刪除一個結構?

struct foo 
{ 
    char* f; 
    int* d; 
    wchar* m; 
} 

我有共享指針的這些結構的載體:

vector<shared_ptr<foo>> vec; 

vec是在堆棧上分配。當它在方法結束時超出範圍時,它的析構函數將被調用。 (右?)這將依次調用向量中每個元素的析構函數。 (對嗎?)delete foo是否只刪除了指針,如foo.f,還是它實際上從堆中釋放內存?

回答

15
delete foo; 

將刪除分配給foo結構的內存,其中包括三個指針。但是,如果你實現了一個明確地刪除它們的析構函數,指針本身指向的內存將只被刪除。

+2

或者,也可以將f,d和m更改爲使用自動或共享指針。 – 2010-06-08 21:19:02

1

它只刪除指針。

1

如果f是堆棧分配,那麼您不要調用delete f,其中f是foo類型的對象。如果該地址存儲在共享指針中,那麼您也不要在類型爲foo的堆分配對象上調用delete fshared_ptr當最後一個參考被釋放時,objets將爲您調用delete

由於你的向量存儲智能指針,當你的向量超出範圍並且foo析構函數將被調用且關聯的存儲空間被釋放時,它們也將超出範圍。 foo的內存只有3個指針的大小。不是這些指針包含的內容。

如果foo的成員是堆分配的,那麼您將需要單獨delete那些。例如,如果它們指向的內存不在對象之間共享,那麼可能在foo析構函數中。


當流出的在方法結束範圍,其析構函數將被調用。 (對吧?)

沒錯。

這將依次調用矢量中每個元素的析構函數。 (對吧?)

沒錯。智能指針的析構函數。

還是它真的從堆中釋放內存?

它調用智能指針的析構函數,如果沒有對該指針的更多引用,那麼它所包含的對象將被刪除並且其內存將被釋放。

1

你的問題似乎出現了一些術語混淆。矢量的析構函數將調用shared_ptr元素的析構函數,而元素將依次在其存儲的指針(如果需要)上執行delete

調用delete foo,其中foo是一個指向struct foo,將調用struct foo*foo佔用的析構函數,然後釋放內存。

上述struct foo的破壞者完全沒有。這是微不足道的。如果不會嘗試釋放由struct foo::f指向的內存或任何其他成員。爲什麼呢?它不知道該內存是否應該被釋放。

事實上,因爲struct foo::~foo是微不足道的,編譯器通常不會嘗試調用它。

10

如果您動態分配foo,如:

foo* f = new foo; 

然後delete f會破壞動態分配foo對象,包括它包含但任何由指針指向的指針,如果他們確確實實點動態分配的對象或對象數組。

如果您分配一個動態分配的foo對象(即的new foo結果)爲shared_ptr(假設TR1或升壓),那麼當最後shared_ptr指的是物體超出範圍delete將被稱爲上的指針最初自動返回new foo。您不必手動執行此操作。

如果你的對象(foo)包含指向動態分配的,它擁有(所以需要在foo的生命週期結束解除分配)對象,那麼強烈建議你寫析構函數在正確解除分配這些對象方式(這將取決於他們如何分配)。

一旦你寫了一個析構函數,你需要考慮是否需要編寫一個拷貝構造函數和複製操作符。當你使用共享指針向量時,你可能會決定不應該複製你的對象。如果是這樣,你可以聲明這些是私有的,不需要提供實現。

您還應該考慮一個或多個構造函數來確保您的指針成員已初始化。如果指針成員從未初始化,那麼如果它們在foo的生命週期中未分配給它們,則它們既不會爲空也不會指向有效的對象,這可能會在析構函數中導致錯誤。

0

當[vec]在方法結束時超出範圍時,將調用其析構函數。 (右?)
正確

這將依次調用向量中的每個元素的析構函數。 (對吧?)
正確,這將刪除容器中的shared_ptr元素,如果它們是最後一個也是它們共享的項目。

是否調用delete foo ...?
你不能刪除foo,這是一個結構。您可以刪除foo的一個實例。
調用delete調用析構函數並釋放foo結構的內存。

foo析構函數是否刪除foo :: f這樣的指針,還是實際上是從堆中釋放內存?
這取決於destructo,在這種情況下,你有一個默認的析構函數,所以...
不,在下面的代碼示例中,你可以看到與foo關聯的默認析構函數無法清除任何指針的一些原因自動引用項目。

{ 
char ca='a', *cb=new char; 
int *i = (int*)malloc(sizeof(int)); 
foo a; 
shared_ptr<foo> b = new foo(); 
a.f = &ca; 
a.d = i; 
b.f = cb; 
}