c++memory-managementpriority-queuefreeremove-method

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


I am programming a priority queue, and I am getting an error:

free(): double free detected in tcache 2

I know that problem is in the PriorityQueue::Remove(int value) method. The method tries to delete an element by value. This method returns TRUE when the element has been deleted and FALSE otherwise.

Here is the code:

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;
}

Specifications:

Priority queue is sorted from the item with highest priority to the item with smallest priority. Method GetHead() returns the first item in the queue with the highest priority. Structure of queue elements have only value and pointer to the next element in the queue.

Please, is there anyone who sees the error in the wrong use of delete?

EDIT: There is no double free. Code works well. Problem was only on my computer - maybe corrupted architecture (don't know). When I tried compile code on another PC it was OK.


Solution

  • I do not see any double-delete in this code, so the problem has to be elsewhere. For instance, if PriorityQueue does not follow the Rule of 3/5/0 properly, and is shallow-copying pointers when it should be deep-copying them. There is not enough code shown to diagnose the root cause of the error.

    However, the code shown is needlessly repetitive, it can be simplified quite a bit:

    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;
    }