出现分段错误

问题描述 投票:0回答:1
#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;
}

上述程序会生成一个称为段错误的运行时错误。如果我从结构 B 中删除 abc 变量,一切都会很好。谁能解释一下这种行为吗?

c++ polymorphic-associations
1个回答
0
投票

这是一个相当常见的问题(或者至少曾经是)。

对基类的指针或引用可以引用派生类的对象。

但是对基类的指针或引用不能可靠地引用派生数组。如果

sizeof(derived) == sizeof(base)
它通常至少看起来有效,但它仍然是错误的。当它们的大小不同时,问题通常会很明显。

官方的标准答案只是“不要这样做。”

非官方的答案是

delete [] ptr2;
不知道数组中所引用的对象的大小。由于
ptr2
是指向基类的指针,因此它尝试遍历该数组,就好像它是基类对象的数组一样。但是当
sizeof(derived) != sizeof(base)
时,这不起作用——它会在数组中创建一个偏移量,这是类型
base
的第二个对象,但由于数组实际上包含派生对象,所以(可能)位于中间的某个位置第一个对象而不是第二个对象的开头。

如果你确实需要做这样的事情,你可以创建一个指向基类的指针数组,并初始化每个指针以引用派生对象。

A ** ptr2 = new A*[2];
A[0] = new B;
A[1] = new B;

// ...

delete A[0];
delete A[1];
delete [] A;

Boost

ptr_vector
可以帮助解决这个问题,如果你关心的话;

© www.soinside.com 2019 - 2024. All rights reserved.