C++代码中p->SomeMethod()是否会因空指针解引用触发错误?
C++悬垂指针调用成员方法的行为分析
先看这段代码:
SomeClass TestMethod(SomeClass c) { SomeClass * p; { SomeClass t; p = &t; } p->SomeMethod(); return *p; }
问题
请问
p->SomeMethod()是否会因空指针解引用而触发错误?我曾用int替代SomeClass测试未出现空指针解引用,但想了解C++标准中的相关行为。
解答
这不是空指针解引用问题,而是访问悬垂指针的问题,具体分析如下:
- 空指针指值为
nullptr(或0)的指针,但这里的p存储的是已销毁对象t的内存地址,指针本身不为空,所以不会触发空指针解引用错误。 - 内部代码块结束时,栈上的局部对象
t会被销毁,其占用的内存会被标记为可复用,但p仍然指向这块内存区域,此时p成为悬垂指针。 - 调用
p->SomeMethod()属于C++标准定义的未定义行为,具体表现取决于函数类型:- 如果
SomeMethod()是普通非虚成员函数,编译器会将其转换为类似SomeClass::SomeMethod(p)的调用形式,因为非虚函数的调用地址是编译期确定的,不需要访问对象的内部数据(比如虚表),所以程序可能不会立刻崩溃——你用int测试时没出问题,就是这个原因。但这并不代表行为合法,只是恰好没触发错误。 - 如果
SomeMethod()是虚成员函数,调用时需要访问对象的虚表指针,而t销毁后该内存区域可能已被篡改,此时大概率会触发崩溃或其他不可预料的异常行为。
- 如果
- C++标准明确规定,通过悬垂指针访问对象的任何操作都是未定义行为,程序可能正常运行、崩溃、产生错误结果,完全取决于编译器实现和运行环境,没有统一的行为保证。
内容的提问来源于stack exchange,提问作者OneHiveRule
相关产品推荐
相关产品推荐

