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

时间:2016-09-28 01:48:40

标签: c++ pointers segmentation-fault

我有一些代码如下所示:

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不是null,因此在内部正确初始化try / catch块。

有人能帮我理解吗?

2 个答案:

答案 0 :(得分:2)

指针初始化为指向自动内部范围内对象的实例。

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

抛出的异常当然会留下声明对象的范围。

换句话说,指针指向的对象只存在于try块内,并且一旦执行离开try块,当然或通过抛出的异常,对象被毁了。

异常被catch块捕获的事实无关紧要。

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

答案 1 :(得分:1)

指针p指向本地对象a,其生命周期限制为try块。在那个街区之外,你有悬挂的指针。因此导致段错误的未定义行为。