调用 operator delete 时的断言

Assertion when operator delete is called

当我的对象被销毁时,我不断遇到断言失败 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)。 我只需要知道我做错了什么。如有任何帮助,我们将不胜感激。

m_pPlayer[0] 是什么类型(如 David 所问。)它是 CSocketPlayer 的基本类型还是 CSocketPlayer 本身。 ?如果它是基类型,则需要将基 class 中的析构函数设为虚拟。这可能与您的问题有关。如果没有,那么问题一定是您已经删除了该对象。这可能是由于竞争条件,其中 2 个线程 运行 具有相同指针的析构函数。 也可能是 new 或 delete 运算符过载,例如从另一个堆分配。猜猜这是牵强附会....但可能..