即使使用虚拟析构函数也会出现删除分段错误

Segmentation Fault with delete even using virtual destructor

本文关键字:删除 错误 分段 虚拟 析构函数      更新时间:2023-10-16

我在删除对象时得到分段错误,被基类的指针引用,即使我已经声明了析构函数虚拟!

这是我的代码

class Shape
{
    public:
        virtual ~Shape()
        {
            cout<<"Shape destructor is called!"<<endl;      
        }
};    
class Line : public Shape
{
    public:
    ~Line()
        {
        cout<<"Line destructor is called!"<<endl;       
    }
};
int main()
{
Line myLine;
Shape* myShapePtr  = &myLine; //Line A
delete myShapePtr;
}

输出

行析构函数被调用!

Shape析构函数被调用!

./runCP.sh: line 2: 2915 Segmentation fault ./a.out

我知道在A行,对象被切片了,这就是我得到这个错误的原因。但是,我还不能弄清楚对象切片是如何导致分割错误的。

如果对象已经切片,则一定没有调用虚析构函数,但这里也调用了虚析构函数。

您只能对已分配new的对象进行delete

myShapePtr不指向与new分配的对象,它指向myLine,这是一个局部变量。

作为一个局部变量,myLine具有自动存储时长。当到达声明它的块末尾的}时,它将自动销毁

您只允许在使用new创建的对象上使用delete,在其他任何对象上使用delete,包括局部变量,是未定义的行为。

不能删除堆栈上的对象。你必须先用new实例化它:

Shape* MyShapePtr = new Line();
delete MyShapePtr;

您在堆栈上声明了myLine。在c++中,当超出作用域(})时,将自动被销毁,因此删除它是不正确的代码。

对于从new返回的内存,应该只(并且总是)使用delete

如果你在面试中遇到过这个问题,那就超载delete operator来安抚面试官吧!