堆栈析构函数中的双重释放或损坏
我很确定问题出在 while (!empty()) pop();
因为在我将其注释掉之后。一切正常。但它不会删除
head
。这部分有什么问题吗?
其意图如下:LinkedList有两个数据成员,head
和tail
。当列表为空时,它们都应该等于0
。当列表非空时,head
和 tail
都应非零,并且它们应分别引用列表中的第一项和最后一项。并且应该有一条通过 next_
指针从 head
到 tail
的路径。如果列表只有一项,则 head == tail
。
#include <iostream>
//stack using linked list
class LinkedList {
public:
LinkedList() : head(0), tail(0) {}
~LinkedList() {
while (!empty()) pop();
std::cout<< "~LinkedList" << std::endl;
}
void pop() {
node* temp;
temp = head;
for ( ; temp->next_ != 0; temp = temp->next_) {
tail = temp;
}
delete temp;
tail->next_ = 0;
std::cout << "pop()" << std::endl;
} //removes, but does not return, the top element
int top() {
return tail->value_;
} //returns, but does not remove, the top element
bool empty() {
return head == 0;
}
void push(const int& value) {
node* element = new node(value);
if (empty()) {
head = tail = element;
} else {
tail->next_ = element;
tail = element;
}
} //place a new top element
private:
class node {
public:
node(const int& input) : value_(input), next_(0) {};
int value_; //store value
node* next_; //link to the next element
};
node* head;
node* tail;
};
int main() {
LinkedList list;
list.push(1);
list.push(2);
std::cout << list.top() << std::endl;
list.pop();
std::cout << list.top() << std::endl;
return 0;
}
通过将析构函数更改为以下代码解决了该问题:
~LinkedList() {
while (head != tail) pop();
delete head;
std::cout<< "~LinkedList" << std::endl;
}
I am pretty sure the problem is at while (!empty()) pop();
because after I commented it out. everything works fine. but it doesn't delete
head
. what's wrong with this part?
The intention is as follows: LinkedList has two data members, head
and tail
. When the list is empty, these should both be equal to 0
. When the list is non-empty, then both head
and tail
shall be non-zero, and they should refer to the first and last items in the list respectively. And there shall be a path from head
to tail
via the next_
pointers. If the list has only one item, then head == tail
.
#include <iostream>
//stack using linked list
class LinkedList {
public:
LinkedList() : head(0), tail(0) {}
~LinkedList() {
while (!empty()) pop();
std::cout<< "~LinkedList" << std::endl;
}
void pop() {
node* temp;
temp = head;
for ( ; temp->next_ != 0; temp = temp->next_) {
tail = temp;
}
delete temp;
tail->next_ = 0;
std::cout << "pop()" << std::endl;
} //removes, but does not return, the top element
int top() {
return tail->value_;
} //returns, but does not remove, the top element
bool empty() {
return head == 0;
}
void push(const int& value) {
node* element = new node(value);
if (empty()) {
head = tail = element;
} else {
tail->next_ = element;
tail = element;
}
} //place a new top element
private:
class node {
public:
node(const int& input) : value_(input), next_(0) {};
int value_; //store value
node* next_; //link to the next element
};
node* head;
node* tail;
};
int main() {
LinkedList list;
list.push(1);
list.push(2);
std::cout << list.top() << std::endl;
list.pop();
std::cout << list.top() << std::endl;
return 0;
}
fixed the problem by changing the destructor to the following codes:
~LinkedList() {
while (head != tail) pop();
delete head;
std::cout<< "~LinkedList" << std::endl;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您的问题的一部分在这里
,
head
何时设置为0
(NULL
)?绝不?You have one part of your problem here
When is
head
set to0
(NULL
)? Never?pop()
是错误的。当只剩下一个元素时,head
和tail
都指向它。因此,当您删除 temp
时,您实际上同时删除了head
和tail
,那么您就是:访问
tail< /code>,它现在是一个已释放的指针,并且
不设置
tail
或head
回到 0pop()
is wrong. When you have only one element left, bothhead
andtail
point to it. So when youdelete temp
, you are in fact deleting bothhead
andtail
, then you are:accessing
tail
, which is now a deallocated pointer, andnot setting
tail
orhead
back to 0如果您
pop()
列表中的最后一个元素,您的pop()
不会修复this->head
。Your
pop()
doesn't fixthis->head
if youpop()
the last element in the list.您可以在开始时添加这些检查。这是一个无聊的解决方案,也许您应该更改整体设计,但此代码应该纠正您当前的
pop
算法。特别是,当弹出最后一项时,head 和 tail 都应该设置为零。另外,它应该是
delete tail->next_;
,而不是delete temp;
,就在tail->next_ = 0;
之前我还没有测试过这个,但它应该可以解决一些问题。
You could add these checks at the start. This is a boring solution, and perhaps you should change your overall design, but this code should correct your current algorithm for
pop
. In particular, when popping the last item, both head and tail should be set to zero.Also, it should be
delete tail->next_;
, notdelete temp;
, just before thetail->next_ = 0;
I haven't tested this, but it should fix some of the problems.