我正试图在c++中使用链表实现堆栈。当我运行代码时,不会向控制台输出任何内容,但它的编译没有出现错误。问题似乎来自于我的顶部节点的指针。我最初使顶部节点没有指针,但是当我试图将其初始化为NULL时,它本身就产生了问题。
代码:
#include <iostream>
using namespace std;
class Stack{
class Node{
int data;
Node* prev;
public:
Node(int x){
data=x;
}
void set_prev(Node nd){
*prev=nd;
}
Node get_prev(){
return *prev;
}
int get_data(){
return data;
}
};
Node* top = NULL;
int count = 0;
public:
void push(int x){
Node new_node(x);
new_node.set_prev(*top);
*top = new_node;
count++;
cout << "Pushing" << endl;
}
void pop(){
if(!is_empty()){
int data = (*top).get_data();
*top = (*top).get_prev();
count--;
cout << "Popping" << endl;
}else{
cout << "Stack is empty." << endl;
}
}
int peek(){
return (*top).get_data();
}
int get_count(){
return count;
}
bool is_empty(){
return !count;
}
};
int main(){
Stack stk;
stk.push(5);
stk.push(13);
cout << stk.peek() << endl;
}
所示代码中有多个与c++中指针和对象的工作方式有关的基本错误。这不仅仅是一个问题或错误,所有这些问题必须在它正常工作之前解决。
Node* prev;
这是Node
类的指针成员。在使用指针引用的对象之前,必须将指针设置为指向有效对象。
所示代码中似乎没有任何内容将prev
设置为指向任何有效的Node
对象。
void set_prev(Node nd){
*prev=nd;
}
这将一个对象分配给prev
指针引用的对象。prev
指针从未被初始化为指向任何对象。因此它的值是未初始化的,是随机的垃圾。赋值给一个由随机的、未初始化的垃圾指针引用的对象是未定义的行为,并且几乎肯定会崩溃。
Node
对象,而不是Node
对象本身;然后将prev
指针设置为传入的指针值。
Node new_node(x);
new_node.set_prev(*top);
所以,在这里,set_prev()
应该用一个指向new_node
的指针来调用,而不是把它(一个副本)传递给set_prev()
。然而,问题远未结束。new_node
是在自动作用域中声明的对象。在这个函数返回之后,new_node
被销毁。任何指向它的现有指针现在都指向一个销毁的、不再有效的对象,进一步对它解引用会导致未定义的行为,以及另一个很可能崩溃的行为。
很明显,根据上下文,这里的意图是在动态范围内实例化一个新的Node
对象,使用new
关键字。因此,pop()
也应该delete
。
这类作业传统上是在引入动态作用域的概念,并使用new
和delete
创建动态作用域中的对象后才会布置的。你应该复习你的课堂笔记,或者教科书材料,以获得关于这个主题的更多信息,以及关于如何正确地创建和销毁对象的更多细节;和正确使用指针。