我有一些代码如下所示:
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块。
有人能帮我理解吗?
答案 0 :(得分:2)
指针初始化为指向自动内部范围内对象的实例。
当执行线程离开作用域时,对象被销毁,指针现在指向被销毁的对象。
抛出的异常当然会留下声明对象的范围。
换句话说,指针指向的对象只存在于try
块内,并且一旦执行离开try
块,当然或通过抛出的异常,对象被毁了。
异常被catch
块捕获的事实无关紧要。
这是使用智能指针的另一个原因。如果对象在动态范围内分配,并且有问题的指针是unique_ptr
或shared_ptr
,则对象仍然可以通过智能指针在catch
块中完全访问,无需额外的工作。
答案 1 :(得分:1)
指针p
指向本地对象a
,其生命周期限制为try
块。在那个街区之外,你有悬挂的指针。因此导致段错误的未定义行为。