调用 operator delete 时的断言
Posted
技术标签:
【中文标题】调用 operator delete 时的断言【英文标题】:Assertion when operator delete is called 【发布时间】:2016-01-04 21:50:49 【问题描述】:当我的对象被销毁时,我不断收到断言失败 dbgheap.c 第 1399 行
_ASSERTE(pHead->nBlockUse == nBlockUse);
我找不到发生这种情况的任何原因。指针在构造函数中正确初始化为 NULL:
CPlayThread()
m_pPlayer[0]= NULL;
m_pPlayer[1]= NULL;
;
这是实际创建对象的代码。
if(pParam->m_pPlayer[0] == NULL) //pParam is a CPlayThread*
if(config.m_nPlayerMode == modeSocket)
pParam->m_pPlayer[0]= new CSocketPlayer();
当线程被销毁时,对象被销毁,这就是断言发生的地方。
~CPlayThread()
if(m_pPlayer[0])
delete m_pPlayer[0];
m_pPlayer[0]=NULL;
if(m_pPlayer[1])
delete m_pPlayer[1];
m_pPlayer[1]= NULL;
;
我在这里完全不知所措。它曾经运行良好,但不知何故,在连续运行三四天后,它开始在客户的位置崩溃。同时我的调试可执行文件开始断言每个 一次玩家被摧毁。在任何给定时间最多有 96 个线程可能正在播放(每个线程有两个玩家,交替 - 根据需要创建和销毁玩家)。因此,在寻找解决方案但没有找到解决方案后,我决定在应用程序执行期间保留对象。所以现在我只有在关闭程序的调试版本时才会得到断言(并且大概在关闭发布版本时会出现不明显的崩溃,这绝不是因为它应该 24/7 运行)。 我只需要知道我做错了什么。任何帮助将不胜感激。
【问题讨论】:
在析构函数中将指针设置为 NULL 不会完成任何事情。对象正在消失。m_Player
是什么类型?它的析构函数是做什么的?什么时候调用~CPlayThread
?
停止使用手动内存分配,您可能会发现问题消失了。
在调用delete
之前,您无需检查指针是否为空值。在 C++ 语言标准中明确要求允许将空指针值传递给 delete
。
对我来说闻起来像 Big Three 问题。
【参考方案1】:
m_pPlayer[0] 是什么类型(就像大卫问的那样。)它是 CSocketPlayer 的基本类型还是 CSocketPlayer 本身。 ?如果它是基类型,则需要将基类中的析构函数设为虚拟。这可能与你的问题有关。如果不是,那么问题一定是您已经删除了该对象。这可能是由于竞速条件,其中 2 个线程使用相同的指针运行析构函数。 也可能是 new 或 delete 运算符重载,例如从另一个堆分配。猜猜这有点牵强..但可能..
【讨论】:
以上是关于调用 operator delete 时的断言的主要内容,如果未能解决你的问题,请参考以下文章
ubuntu tensorflow报错:ValueError:No op named NonMaxSuppressionV3 in defined operations.
为啥 std::rel_ops::operators 在 C++20 中会被弃用?
为啥 std::optional operator* 没有 has_value() 的调试模式断言?
c++ new operator和operator new,delete operator和operator delete