在try/catch外部声明但在内部初始化的指针会导致未定义的行为

Pointer declared outside of try/catch but initialized inside causes undefined behaviour?

本文关键字:指针 未定义 初始化 catch try 外部 声明 在内部      更新时间:2023-10-16

我有一个代码,看起来像下面的:

class ClassA
{
public:
    ClassA(string p1, string p2);
    void DoSomething();
};
int main()
{
    ClassA *p = NULL;
    try
    {
        // ...
        // some external input that can throw
        // ...
        ClassA a{"some", "params"};
        p = &a;
    }
    catch(...)
    {
        // print error
    }
    if (p != NULL) {
        p->DoSomething(); // <- causes segfault
    }
}

道歉,如果这是坏/愚蠢的代码(我是新的c++),但为什么调用a->DoSomething()导致段错误发生?显然,p被声明在try/catch块的范围之外,p != NULL总是返回true,表明p不为空,因此在try/catch块内部被正确初始化。

有人能帮我理解一下吗?

指针初始化为指向自动内部作用域中对象的实例。

当执行线程离开作用域时,对象被销毁,指针现在指向被销毁的对象。

抛出的异常当然会离开声明对象的作用域。

换句话说,指针指向的对象只存在于try块中,一旦执行离开try块,自然地,或者通过抛出异常,对象将被销毁。

异常被catch块捕获的事实是不相关的。

这是使用智能指针的另一个原因。如果对象是在动态范围内分配的,并且所讨论的指针是unique_ptrshared_ptr,则通过智能指针在catch块中仍然可以完全访问该对象,而不需要额外的工作。

指针p指向局部对象a,该对象的生存期仅限于try块。在那个块的外面有一个悬浮指针。因此,导致段错误的未定义行为。