反转使用链表实现的堆栈
Reversing a stack implemented using a linked list
这是一个非常简单的程序,它使用链表实现堆栈。请帮助我找出使程序在运行时崩溃的逻辑错误。
class LLStack {
public:
struct Node {
int data;
Node* next;
Node(int n) {
data = n;
next = 0;
}
Node(int n, Node* node) {
data = n;
next = node;
}
};
LLStack();
LLStack(const LLStack&);
LLStack& operator = (const LLStack&);
~LLStack();
void push(int);
int pop();
int top();
bool isEmpty();
void flush();
private:
Node* head;
};
LLStack::LLStack() {
head = 0;
}
LLStack::LLStack(const LLStack& s) {
head = new Node(NULL);
head->data = s.head->data;
head->next = new Node(*(s.head->next));
}
LLStack::~LLStack() {
this->flush();
}
LLStack& LLStack::operator = (const LLStack& s) {
this->head = new Node(NULL);
this->head->data = s.head->data;
this->head->next = new Node(*(s.head->next));
return *this;
}
void LLStack::push(int x) {
if (head == 0) head = new Node(x);
else {
Node* temp = new Node(x, head);
head = temp;
}
}
int LLStack::pop() {
if (head == 0) {
cout << "nnNo elements to popnn";
return -1;
}
else {
Node* temp = head;
int n = temp->data;
head = temp->next;
delete temp;
return n;
}
}
int LLStack::top() {
if (head == 0) {
cout << "nnNo elements in the stacknn";
return -1;
}
else {
return head->data;
}
}
bool LLStack::isEmpty() {
return (head == 0);
}
void LLStack::flush() {
if (head == 0) {
cout << "nnNo elements in the Stack to flushnn";
return;
}
cout << "nnFlushing the Stack: ";
Node* temp = 0;
while (head != 0) {
temp = head;
cout << temp->data << " ";
head = head->next;
delete temp;
}
cout << endl << endl;
}
这是麻烦制造者的功能:
void reverseStack(LLStack& s1) {
LLStack s2;
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
s1 = s2;
}
int main() {
LLStack s;
s.push(1);
s.push(2);
s.push(3);
s.push(4);
s.push(5);
reverseStack(s);
cout << "nnFlushing s:n";
s.flush();
system("pause");
return 0;
}
我已经实现了自己的复制构造函数和复制赋值运算符。我不明白为什么它在运行时崩溃。刷新时,它会在崩溃之前显示垃圾值。
问题是你的复制赋值运算符。考虑:
void reverseStack(LLStack& s1) {
LLStack s2;
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
s1 = s2;
}
一切正常,直到您从函数返回,此时调用 s2
的析构函数。析构函数调用 flush()
,这将删除 s2
的所有堆栈元素。在您的复制赋值运算符(和复制构造函数)中,您创建两个节点:head
和 head->next
;其余节点在两个堆栈之间共享,因此删除s2
后,s1.head->next->next
指向已删除的节点,但您仍会尝试访问它。
解决方案是让复制赋值运算符(和复制构造函数)创建堆栈的适当深层副本,而不仅仅是前两个元素,如下所示(也负责自赋值):
LLStack& LLStack::operator=(const LLStack& s) {
if (this==&s) return *this; // self assignment
flush(); // avoid memory leak
head = new Node(*s.head);
Node* s_ptr = s.head;
Node* t_ptr = head;
while (s_ptr->next) {
t_ptr->next = new Node(*s_ptr->next);
s_ptr = s_ptr->next;
t_ptr = t_ptr->next;
}
return *this;
}
请记住,复制构造函数也应该这样做。
相关文章:
- 如何在 c++ 中实现堆栈数组?
- 使用链表实现堆栈时出错
- 在给定程序中降低矢量数组实现堆栈的时间复杂度有哪些不同的可能方法?
- C++ 使用数组实现堆栈
- 关于在C 中实现堆栈的问题
- 使用链接列表在C 中实现堆栈
- c++ 中 if 语句中的多个条件(通过链表实现堆栈)
- C 内存泄漏错误在实现堆栈类时
- 尝试实现堆栈时C++未定义的引用
- 链表与动态数组用于使用向量类实现堆栈
- 在C++中实现堆栈类
- 可视化 在C++中实现堆栈
- 使用链接列表实现堆栈,调试断言失败
- 我怎样才能实现堆栈的向量
- 在没有动态内存分配的情况下实现堆栈
- 如何使用 std::vector 实现堆栈
- 在c++中使用链表实现堆栈
- 在哪里实现堆栈类(在非递归二进制搜索函数中使用)
- 使用双链表实现堆栈的错误
- 在c++中使用链表实现堆栈,复制构造函数