重置未定义行为后是否使用 shared_ptr?

Is using shared_ptr after reset undefined behaviour?

我有这个测试程序:

#include <iostream>
#include <memory>

class A {
public:
    A()
    {
        std::cout<<"A Constructor\n";
    }

    ~A(){
        std::cout<<"A Destructor\n";
    }

    void show()
    {
        std::cout<<"A::show()"<<'\n';
    }
};

int main()
{
    auto p1 = std::make_shared<A>();
    // Relinquishes ownership of p1 on the object
    // and pointer becomes NULL
    p1.reset();
    std::cout<<p1.get()<<'\n';
    std::cout<<p1.use_count()<<'\n';
    p1->show();
    return 0;
}

产生此输出:

A Constructor
A Destructor
0
0
A::show()

我通过 gdb 运行 看到了:

:
:
(gdb) s
A::show (this=0x0) at so.cpp:18
18              std::cout<<"A::show()"<<'\n';
(gdb) s
A::show()
:

A::show (this=0x0) at so.cpp:18表示底层资源为空。我查看了 another 问题,但原始指针被用于调用成员函数。这种情况是否与该问题中的情况太相似,因为 p1->show() 也应该等同于 p1.get()->show();。我的理解正确吗?

只需向 class 添加一个数据成员,您就可以在视觉上看到未定义的行为。

#include <iostream>
#include <memory>

class A {
public:
    A()
    {
        std::cout<<"A Constructor\n";
    }

    ~A(){
        std::cout<<"A Destructor\n";
    }

    void show()
    {
        std::cout<<"A::show()"<<'\n';
        ++x;
    }

    int x = 0;
};

int main()
{
    std::shared_ptr<A> p1(new A);
    // Relinquishes ownership of p1 on the object
    // and pointer becomes NULL
    p1.reset();
    std::cout<<p1.get()<<'\n';
    std::cout<<p1.use_count()<<'\n';
    p1->show();
    return 0;
}

例如在 运行 时出现这样的错误

Runtime error #stdin #stdout 0s 4280KB

可以显示。

那是空指针被用来访问数据成员。