循环双链列表内存释放

清理循环链表的内存时遇到严重麻烦。我想我理解这个问题。我的头指针有N个分配,而构建指针有N-1个分配。 addback函数只能有一个整数,我不能使用容器或向量。

void Queue::addBack(int passed_Val)
{
    if (head == nullptr) //takes care of first node when list is empty
    {

        head = new QueueNode;//head is my building now
        cout<<"head is "<<sizeof(head)<<" bytes"<<endl;
        head->val = passed_Val;
        head->next = head;//this make an infinite loop
        head->prev = head;
        cout<<"node[0] mem allocated "<<head<<endl;

    }
    else 
    {
        //build next will always have N-1 address,where N = number of addresses
        //head points to. I don't want build to point to head when N=1
        //          have tempPtr point to old address                               
        QueueNode* tempPrev = head->prev;//this will always point to the last node added!   
        QueueNode* build = new QueueNode;
        build->next=head;
        cout<<"build is "<<sizeof(build)<<" bytes"<<endl;
        cout<<"node[1] mem allocated "<< build <<endl;
        cout<<"node[1] "<< head <<endl;
        build->val=passed_Val;

        build->next = head;
        head->prev = build;

        tempPrev->next = build;
        build->prev = tempPrev;

    }

我的析构函数如下所示

Queue::~Queue()
{
    if(head !=nullptr)//needed because i don't want to deallocate head if it was never called
    {
        QueueNode* deletePtr = head->next;
            cout<<"deallocating node[0] "<<head<<endl;
            delete head;

            while(deletePtr !=head)
            {
                delete deletePtr;
                cout<<"deallocating pointer "<<deletePtr<<endl;
                deletePtr =deletePtr->next;
            }           
    }
}

我已经考虑过在(head == nullptr)条件下使构建指针等于head指针,但是我遇到了更多问题。这是我的valgrind的结果

循环双链列表内存释放

我认为这是我的主要问题 == 30923 ==地址0x5a225e0是大小为24的块中的0个字节

因此,如果我理解正确,我正在尝试释放已经释放的内存?如何在析构函数中解决此问题?我试图弄乱我的addback函数,但最终会丢失节点或出现更多的内存泄漏:(

fangchufeng 回答:循环双链列表内存释放

            delete deletePtr;

这将销毁deletePtr所引用的任何对象。之后立即:

            deletePtr =deletePtr->next;

这会尝试引用deletePtr->next。正如我们刚刚确定的那样,deletePtr的对象已被破坏,对其取消引用成为未定义的行为。

这可能不是显示代码的唯一问题。如果没有minimum reproducible example,就不可能最终确定这一点,可能还会有其他问题。但这绝对是其中之一。

,

要添加到@SamVarshavchick给出的答案,此处的代码有缺陷:

delete head;
while(deletePtr != head)  // <-- You are comparing deletePtr to a deleted pointer?

鉴于所有这些,Queue析构函数似乎比应有的复杂。以下是我所期望的:

Queue::~Queue()
{
    QueueNode* deletePtr = head;
    QueueNode* nextPtr = nullptr;
    while ( deletePtr )
    {
       nextPtr = deletePtr->next;
       delete deletePtr;
       deletePtr = nextPtr;
    }
}

请注意,由于函数head仅在非空值上输入,因此无需在函数开始时明确检查while是否为空。

,

我是毁灭者!这是我解决的方法

Queue::~Queue()
{
    int i=1;
    if(head !=nullptr)//needed because i don't want to deallocate head if it was never called
    {

        QueueNode* stop = head->prev;

        QueueNode* deletePtr = head->next;//tractor node[1]
        QueueNode* temp = head;// cutter            node[0]

        if(deletePtr ==head)// N=1
        {
            delete deletePtr;
        }
        else if(deletePtr == stop)//N=2
        {
             deletePtr = stop;
             delete deletePtr; 
             delete head;
        }
        else//N >=3
        {   
            while (temp != stop)//last node
            {
                delete temp;      //delete node[0]
                cout<<"temp "<<temp<<endl;
                cout<<"deletePtr "<<deletePtr<<endl;
                temp= deletePtr;// node[1]                                         
                deletePtr = deletePtr->next;//node[2]       
                cout<<"temp "<<temp<<endl;
                cout<<"deletePtr "<<deletePtr<<endl;


            }       
            delete stop;
        }//end N>=3

    }
}
本文链接:https://www.f2er.com/3085283.html

大家都在问