You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基类指针删除派生类数组触发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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 18:13:17