删除对象时C++断言错误
C++ assertion error while deleting object
我有奇怪的断言错误,我找不到这段代码有什么问题。
断言表达式为 _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)。但是我需要,该创建方法可以创建继承MyObject的任何对象。就像在代码的第一次和平中一样。
对此断言错误的任何帮助将不胜感激。谢谢。
问题是您的 MyObject 类缺少虚拟析构函数,并且您尝试使用指向基类的指针在派生类的指针上调用delete
MyObject
。 如果基类析构函数不是虚拟的,则通过基类指针对派生对象发出delete
是未定义的行为。
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>();
}
问题是您尝试通过 MyObject 指针删除对象,并且 MyObject 析构函数不是虚拟的。你可以使MyObject的析构函数成为虚拟的,然后你可以通过指向MyObject的指针删除子类对象。有关此问题的更多详细信息,请参阅此问题
我认为问题出在多重继承上。下面是重现问题的简化方法。它可以通过以下方式修复
- 将其强制转换为派生最多的类型 OR
- 使基类的析构函数是虚拟的。
在您的情况下,虚函数方法是最好的,因为建议将基类析构函数设置为虚拟,以便通过继承层次结构获取销毁调用。
class A
{
};
class B
{
};
class C : public A, public B
{
};
int main()
{
// Fails with memory heap error
B* pB = new C();
delete pB;
}
要修复它
int main()
{
B* pB = new C();
// Casting it to the "full" type will fix it
C* pC = static_cast<C*>(pB);
delete pC;
}
第二个程序有效,因为它类似于下面。
int main()
{
// Pointer to the "full" type works
C* pC = new C();
delete pC;
}
- OpenCV - Python 断言错误:SAD 算法 - 立体相机视差图计算
- 我收到一个断言错误,但是当我编写 cout 语句时,它会消失
- 尝试删除指向派生对象的基指针时断言错误
- Sysmalloc:使用向量的断言错误
- OpenCV CV 查找单应断言错误计数器 = > 4
- Mat的convertTo函数在OpenCV中将灰度图像的类型转换为CV_32F时抱怨断言错误
- 是什么导致我的C 代码中的断言错误
- 迭代器取消引用断言错误
- boost::shared_ptr 断言错误与 boost::asio:io_service
- CDao数据库断言错误
- STL 迭代器:断言错误
- 断言错误,字符串下标超出范围
- 调试断言错误-OpenCV
- 向量push_back会导致断言错误,但列表push_back有效
- 如何在子进程中禁用断言错误对话框
- OpenCV.norm中的断言错误
- 将功能区添加到现有的非功能区 mfc 项目 - 在 VS2010 中断言错误
- 访问指向像素openCV的指针时发生断言错误
- 断言错误,即使在使用 new 初始化字符指针后也是如此
- 使用结构向量 c++ 的断言错误