4

我是这个概念的新手,所以不要对我太苛刻。为什么这段代码不产生析构函数调用?类的名称是不言自明的。SString 将在 ~SString() 中打印一条消息。它只打印一条析构函数消息。

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

这是内存泄漏吗?暗示。对于 smart_ptr 来自 这里

编辑:

//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

4 回答 4

8

通过new smart_ptr<SString>(new SString("but lost"));您创建一个新的、动态分配的智能指针。您不会将分配的结果(指向 a 的指针shared_ptrSString存储在任何地方,它是悬空的......因为您不存储结果,所以您也不能调用delete它 - 因此它的析构函数不会被调用,反过来也SString不会调用所包含对象的析构函数!

如果你试试

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

相反,您将看到在这种情况下也调用了析构函数。

但是,这不是明智的使用 a smart_ptrsmart_ptr已创建,因此您无需delete手动调用;因此,不要那样使用它们;在您的第一个语句中使用它们!

于 2012-09-14T14:26:41.813 回答
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;
于 2012-09-14T14:26:49.790 回答
5

是的,智能点本身已经泄露。(以及它所引用的任何内容)。

我想不出new一个智能指针的好理由......

于 2012-09-14T14:26:24.893 回答
3

是的,这是内存泄漏,您正在泄漏第二个智能指针及其内容。

原因是第一个智能指针是在堆栈上创建的,所以它的生命周期限定在它声明的块中,之后它会被自动销毁。

第二个是在堆上创建的,这意味着它会一直存在,直到你销毁它delete,此时它的析构函数将被调用(并且SString它所持有的析构函数)。

于 2012-09-14T14:27:53.967 回答