free():在 PriorityQueue 移除方法中的 tcache 2 中检测到双重释放

free(): double free detected in tcache 2 in PriorityQueue remove method

我正在编写优先级队列,但出现错误:

free(): double free detected in tcache 2

我知道问题出在 PriorityQueue::Remove(int value) 方法中。该方法尝试按值删除元素。此方法 returns 当元素已被删除时为 TRUE,否则为 FALSE。

代码如下:

bool PriorityQueue::Remove(int value)
{
    Element_t *actualItem = this->GetHead();

    Element_t *temporary = nullptr;

    if (actualItem == nullptr) {

        return false;
    }

    while (actualItem != nullptr) {

        if (actualItem->value == value) {

            if (actualItem == this->GetHead()) {
                if (actualItem->pNext == nullptr) {
                    delete actualItem;
                    m_pHead = nullptr;

                    return true;
                }

                m_pHead = actualItem->pNext;
                delete actualItem;

                return true;
            }


            if (actualItem->pNext == nullptr) {
                delete actualItem;
                temporary->pNext = nullptr;

                return true;
            }

            temporary->pNext = actualItem->pNext;
            delete actualItem;

            return true;
        }

        temporary = actualItem;
        actualItem = actualItem->pNext;
    }

    return false;
}

规格:

优先级队列从优先级最高的项目到优先级最低的项目排序。方法 GetHead() returns 队列中具有最高优先级的第一项。队列元素的结构只有值和指向队列中下一个元素的指针。

请问有没有人看到错误使用delete的错误?

编辑: 没有双重免费。代码运行良好。问题只在我的电脑上——可能是损坏的架构(不知道)。当我尝试在另一台 PC 上编译代码时,它没问题。

我在这段代码中没有看到任何双删除,所以问题一定出在其他地方。例如,如果 PriorityQueue 没有正确地遵循 Rule of 3/5/0,并且在应该对它们进行深度复制时浅复制指针。显示的代码不足,无法诊断错误的根本原因。

然而,显示的代码是不必要的重复,可以简化很多:

bool PriorityQueue::Remove(int value)
{
    Element_t *actualItem = m_pHead;
    if (actualItem)
    {
        Element_t *temporary = nullptr;
        do
        {
            if (actualItem->value == value)
            {
                if (actualItem == m_pHead)
                    m_pHead = actualItem->pNext;
                if (temporary)
                    temporary->pNext = actualItem->pNext;
                delete actualItem;
                return true;
            }
            temporary = actualItem;
            actualItem = actualItem->pNext;
        }
        while (actualItem);
    }
    return false;
}