2012-09-14 47 views
4

我是新來的概念,所以不要對我很難。 爲什麼這段代碼不產生析構函數調用? 類的名稱是不言自明的。 SString將在〜SString()中打印一條消息。 它只打印一個析構函數消息。可能的mem泄漏?

int main(int argc, TCHAR* argv[]) 
{ 
smart_ptr<SString> smt(new SString("not lost")); 
new smart_ptr<SString>(new SString("but lost")); 
return 0; 
} 

這是內存泄漏嗎? 該impl。對於smart_ptr是here

編輯:

//copy ctor 
    smart_ptr(const smart_ptr<T>& ptrCopy) 
    { 
     m_AutoPtr = new T(ptrCopy.get()); 
    } 
    //overloading = operator 
    smart_ptr<T>& operator=(smart_ptr<T>& ptrCopy) 
    { 
     if(m_AutoPtr) 
      delete m_AutoPtr; 
     m_AutoPtr = new T(*ptrCopy.get()); 
     return *this; 
    } 
+4

什麼是'new''d,必須'delete''d。 – DCoder

+0

動態內存越來越無處... !!! –

+3

不管你做什麼,除了學習練習之外,不要使用該實現。即使在糾正了過時的標題名稱並修復了明顯的錯誤之後,它的複製語義仍然無法解決。在實際代碼中使用'std :: unique_ptr'和'std :: shared_ptr'。 –

回答

8

通過new smart_ptr<SString>(new SString("but lost"));要創建一個新的,動態分配的智能指針。您不會將分配的結果(指向shared_ptr的指針存儲到SString)存儲在任何地方,因爲您不存儲結果,所以也不能調用delete - 因此它是析構函數「不會被調用,反過來也不會調用被包含對象的析構函數!

如果您嘗試

smart_ptr<SString> *p = new smart_ptr<SString>(new SString("but lost")); 
delete p; 

相反,你會看到還呼籲這種情況下,析構函數。

但是,這並不合理地使用smart_ptrsmart_ptr被創建,以便您不需要需要手動撥打delete;因此,不要那樣使用它們;在你的第一個陳述中使用它們!

5

是,智能點本身被泄露。 (和任何它有一個參考)。

我想不出一個很好的理由new智能指針...

8

智能指針的一點是,你應該只自動智能指針對象:

{ 
    smart_ptr<Foo> p(new Foo); 
} 
// bye bye Foo 

你的第二行,但是,創建一個動態智能指針,他的生命永遠結束!因此它永遠不會有機會摧毀它負責的對象。

你將不得不手動刪除智能指針本身,因此它可以依次清理對象:

auto sp = new smart_ptr<Foo>(new Foo); 
//       ^^^^^^^ 
//  ^^^^^^^^^^^^^^   +------< dynamic Foo, handled by the SP 
//      | 
//      +---------------< dynamic smart pointer, handled by YOU 

delete sp; 
+8

「你將不得不手動刪除智能指針本身 - 」或者把它放在一個聰明的......哦,沒關係;-) –

+0

@SteveJessop:我看到你在那裏做了什麼...... –

3

是的,它是內存泄漏,你漏第二智能指針和其內容。

原因是第一個智能指針是在棧上創建的,所以它的生命週期的範圍是它聲明的塊,然後它會被自動銷燬。

第二個是在堆上創建的,這意味着它將一直存在,直到你用delete銷燬它,此時它的析構函數將會被調用(並且與它所持有的SString的析構函數一致)。