2012-09-14 28 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的析构函数一致)。