删除对象时C ++断言错误 [英] C++ assertion error while deleting object

查看:168
本文介绍了删除对象时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>();
}< - 析构函数的调用

想法是一个对象女巫继承Creator ,可以创建任何其他对象,并保存指向这些对象的指针。而程序员可以使用引用。当super对象被销毁时,所有的sub对象也被销毁。



如果我更改为:

 模板< 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();
}


$ b $ p现在create方法只创建一种类型的对象。
但是我需要,create方法可以创建任何继承MyObject的对象。就像在代码的第一个和平。



任何帮助这个断言错误将不胜感激。感谢。

解决方案

问题是你的MyObject类缺少一个虚拟析构函数,你试图调用 delete ,使用指向基类 MyObject 的指针指向派生类的指针。如果基类析构函数不是虚拟的,则通过基类指针在派生对象上发出 delete 是不确定的行为。



< blockquote>

5.3.5删除(第3段)



在第一个选择(删除对象)中,如果
操作数与其动态类型不同,静态类型应为操作数动态类型的基类,而静态类型应具有虚拟析构函数或行为未定义


一旦析构函数在基类 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>();
}


I have strange assertion error and I can not find what is wrong with this code.

Assertion expression is _BLOCK_TYPE_IS_VALID(pHead->nBlockUse).

I simplified code a bit for better readability.

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

The idea is that an object witch inherits Creator, can create any other object, and hold pointers to those objects. While programmer can work with references. And when "super" object is destroyed, all "sub" objects are destroyed too.

Program works like a charm if I change to:

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();
}

Now create method creates only one type of object ( object A in this example ). But I need, that create method could create any object that inherits MyObject. Like in first peace of code.

Any help for this assertion error would be appreciated. Thanks.

解决方案

The issue is that your MyObject class lacks a virtual destructor, and you're attempting to call delete on a pointer to the derived class using a pointer to the base class MyObject. Issuing a delete on a derived object through a base class pointer is undefined behavior if the base class destructor is not virtual.

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.

Once the destructor is made virtual in the base class MyClass, the following works correctly in 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>();
} 

这篇关于删除对象时C ++断言错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆