基类指针删除派生类数组触发Segmentation fault的原因求解
问题解释:派生类数组用基类指针
delete[]时的崩溃差异 首先看问题中的代码:
#include <iostream> using namespace std; struct A { virtual ~A() { cout << 0 << endl;}; }; struct B : A { int abc; ~B(){ cout << 3;} }; int main() { A* ptr2 = new B[2]; delete [] ptr2; }
核心原因:未定义行为的不同表现
C++明确规定:使用基类指针调用delete[]删除派生类数组属于未定义行为,但有无abc成员导致了两种截然不同的运行结果,背后是编译器处理数组析构的逻辑差异:
当
B没有abc成员时:B的内存大小和基类A完全一致(只有虚表指针)。delete[]处理基类指针时,会按A的大小作为步长遍历数组,刚好和B的大小匹配,所以能正确定位每个B对象,依次调用~B()和~A(),不会越界访问内存,因此程序“正常运行”。当
B有abc成员时:B的内存大小比A大(比如A占8字节,B占12字节)。delete[]仍按A的大小(8字节)跳转寻找下一个元素,这时候会跳到第一个B对象的内存中间位置,访问这个非法地址直接触发段错误。
这种“有时正常有时崩溃”是未定义行为的典型表现,完全依赖内存布局和编译器实现,绝对不能依赖这种巧合。正确的做法是始终用派生类类型的指针来delete[]派生类数组。
内容的提问来源于stack exchange,提问作者Hardik
相关产品推荐
相关产品推荐

