具有未在堆上分配的对象的AutoPointer

时间:2012-05-16 11:40:35

标签: c++

一旦超出范围,自动指针在内部调用它指向的对象上的删除。如果我们分配在堆上创建的对象,这可以正常工作。但是如果我尝试分配一个不是在堆上创建的对象,它会崩溃,因为删除会被调用两次。首先是auto_ptr本身,第二个是当对象超出范围时,它的析构函数再次被调用。 如下图所示,

#include <iostream>
#include <memory>

using namespace std;

class sample
{
      public:
             sample() { puts("sample"); }
             ~sample() { puts("~sample"); }
};

int main()
{
    sample sObj;
    auto_ptr<sample> samplePtr(&sObj);
}

这是否意味着我们可以使用auto_ptr仅保存在堆上创建的对象?

5 个答案:

答案 0 :(得分:3)

是的,确切地说,您只能将auto_ptr用于堆分配的对象。技术原因是auto_ptr析构函数调用delete并且对未在堆上分配的对象调用delete未定义的行为,这会导致堆崩溃,多次运行析构函数,你不应该指望的任何其他事情,不应该推测。

答案 1 :(得分:2)

简短回答 - 是的。

这意味着您将管理内存的责任传递给auto_ptr。但是如果你在自动存储中创建对象,那么责任在于运行时,所以你不能放弃它。

答案 2 :(得分:2)

自动清理对象(您在堆栈中称为“对象”)的对象会自动清理。存在auto_ptr以便于清理使用new分配的对象(它在指针上调用delete)。将auto_ptr用于具有自动存储持续时间的对象是没有意义的,因为它们未与new一起分配。

答案 3 :(得分:2)

如果使用std :: auto_ptr,则只能保存在堆上创建的对象。

但是如果你使用例如boost :: shared_ptr,你可以指定一个删除器 当对象离开范围时调用。因此,如果您在堆栈上引用对象,则可以 使用实际上什么都不做的自定义删除器 有关详细信息,请参阅boost::shared_ptr

std :: auto_ptr从C ++ 11开始不推荐使用 见C++11 std::auto_ptr deprecated

答案 4 :(得分:1)

这是否意味着我们可以使用auto_ptr来仅保存在堆上创建的对象? 是的。
自动对象会自动销毁,因此它们不需要像智能指针那样的任何包装器。

请注意,您可以使用shared_ptrunique_ptr,这样您就可以调用自定义deletor函数。通过使用此自定义deletor功能,您可以使用自定义内存分配器而不是new

auto_ptr已被弃用,C ++标准建议unique_ptr是更好的选择。