使用另一个指针在一个“ unique_ptr”拥有的对象上调用“ delete”

时间:2018-10-21 19:36:33

标签: c++ c++11 smart-pointers unique-ptr delete-operator

我有一个指向import java.io.*; import java.net.*; public class MyClient { public static void main(String[] args) { try{ Socket s=new Socket("localhost", 4242); DataOutputStream dout=new DataOutputStream(s.getOutputStream()); dout.writeUTF("Hello Server"); dout.flush(); dout.close(); s.close(); }catch(Exception e){e.printStackTrace();} } } 运算符初始化的类的指针。然后,我使用此指针来设置new。现在,据我所知,以下代码具有双重删除功能:一次手动调用std::unique_ptr运算符,然后当唯一指针超出范围时。该代码如何“正确”运行,即没有运行时异常?

delete

输出:

#include <iostream>
#include <memory>

class A
{
public:
    A()
    {
        std::cout<<"In A::A()\n";
    }
    ~A()
    {
        std::cout<<"In A::~A()\n";
    }
    void printMyStr()
    {
        std::cout<<"In A::printMyStr()\n";
    }
};

int main()
{
    std::cout<<"hello world!\n";
    A * pa = new A();
    std::unique_ptr<A> upa(pa);
    pa->printMyStr();
    upa->printMyStr();
    delete pa;  // How does this not create problems?
    return 0;
}

很明显,即使只创建了一个对象,析构函数也会运行两次。这怎么可能?

注意:我在64位linux上使用gcc 7.3.0。

2 个答案:

答案 0 :(得分:4)

重复删除是不确定的行为。

未定义的行为不能保证运行时异常;定义。未定义的行为意味着任何事情都可能发生。这可能包括时间旅行,格式化硬盘,将浏览器历史记录通过电子邮件发送给您的联系人,或者什么都不做。

我还没有经历过通过电子邮件发送浏览器历史记录的经历。我已经休息了。

答案 1 :(得分:0)

如果在unique_ptr实例超出范围之前的某个时刻,您决定要删除托管对象,只需执行unique_ptr_instance.reset(nullptr)。这将调用删除程序,并使托管对象变为nullptr,并在实例最终超出范围时删除该空对象。