调用 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 中会被弃用?

iscsi使用教程(中)

为啥 std::optional operator* 没有 has_value() 的调试模式断言?

c++ new operator和operator new,delete operator和operator delete

调试断言失败错误