清理循环链表的内存时遇到严重麻烦。我想我理解这个问题。我的头指针有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函数,但最终会丢失节点或出现更多的内存泄漏:(
答案 0 :(得分:3)
delete deletePtr;
这将销毁deletePtr
所引用的任何对象。之后立即:
deletePtr =deletePtr->next;
这会尝试引用deletePtr->next
。正如我们刚刚确定的那样,deletePtr
的对象已被破坏,对其取消引用成为未定义的行为。
这可能不是显示代码的唯一问题。如果没有minimum reproducible example,就不可能最终确定这一点,可能还会有其他问题。但这绝对是其中之一。
答案 1 :(得分:1)
要添加到@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
是否为空。
答案 2 :(得分:0)
我是毁灭者!这是我解决的方法
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
}
}