其他分享
首页 > 其他分享> > 删除对象时出现C断言错误

删除对象时出现C断言错误

作者:互联网

我有奇怪的断言错误,我找不到这个代码有什么问题.

断言表达式是_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse).

为了更好的可读性,我简化了一些代码.

class Creator
{
public:
    virtual ~Creator()
    {
        for (MyObject* item : _list)
        {
            delete item; <-- assertion error here
            item = 0;
        }
        _list.clear();
    }

    template <class T>
    T& create()
    {
        T * item = new T();
        _list.push_back(item);
        return *item;
    }

private:
    std::list<MyObject*> _list;
};

class A : public MyObject, public Creator
{
};

class B : public MyObject, public Creator
{
};

int main()
{
    A a;
    a.create<A>();
} <-- call of destructor

这个想法是一个继承Creator的对象,可以创建任何其他对象,并保持指向这些对象的指针.程序员可以使用引用.当“超级”对象被破坏时,所有“子”对象也被破坏.

如果我改变为以下程序,程序就像一个魅力:

template <class T>
class Creator
{
public:
    virtual ~Creator()
    {
        for (T* item : _list)
        {
            delete item;
            item = 0;
        }
        _list.clear();
    }

    T& create()
    {
        T * item = new T();
        _list.push_back(item);
        return *item;
    }

private:
    std::list<T*> _list;
};

class A : public MyObject, public Creator<A>
{
};

class B : public MyObject, public Creator<B>
{
};

int main()
{
    A a;
    a.create();
}

现在create方法只创建一种类型的对象(在本例中为对象A).
但我需要,create方法可以创建任何继承MyObject的对象.就像在第一次和平的代码.

任何有关此断言错误的帮助将不胜感激.谢谢.

解决方法:

问题是您的MyObject类缺少虚拟析构函数,并且您尝试使用指向基类MyObject的指针在指向派生类的指针上调用delete.如果基类析构函数不是虚拟的,则通过基类指针对派生对象发出删除是未定义的行为.

5.3.5 Delete (Paragraph 3)

In the first alternative (delete object), if the static type of the
operand is different from its dynamic type, the static type shall be a base class of the operand’s dynamic type and the static type shall have a virtual destructor or the behavior is undefined.

一旦析构函数在基类MyClass中变为虚拟,下面的代码在Visual Studio 2013中正常工作:

#include <list>
struct MyObject 
{
    virtual ~MyObject() {}
};

class Creator
{
public:
    virtual ~Creator()
    {
        for (MyObject* item : _list)
        {
            delete item; 
            item = 0;
        }
        _list.clear();
    }

    template <class T>
    T& create()
    {
        T * item = new T();
        _list.push_back(item);
        return *item;
    }

private:
    std::list<MyObject*> _list;
};

class A : public MyObject, public Creator
{
};

class B : public MyObject, public Creator
{
};

int main()
{
    A a;
    a.create<A>();
} 

标签:assertion,c,inheritance,runtime-error,delete-operator
来源: https://codeday.me/bug/20191003/1849971.html