【问题标题】:How do I get this Linked List Stack implementation to run in C++?如何让这个 Linked List Stack 实现在 C++ 中运行?
【发布时间】:2021-10-19 20:24:25
【问题描述】:

我正在尝试使用 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;
}

【问题讨论】:

  • 在 set_prev 中你为什么不接受Node* 并将prev 设置为那个?同样在push new_node 将在函数结束时被销毁。您应该使用动态分配。此外,我看不出您如何在*prev = nd 处没有遇到段错误,因为prev 从未初始化过。是的,在取消引用 top 之前进行了测试和段错误。该程序没有输出任何东西,因为它事先崩溃了
  • @Lala5th 关于段错误,应该没问题,因为在初始化之前从未访问过 prev。
  • 那么你在初始化之前取消引用它。 prev*prev 不是一回事。要初始化prev,您需要new malloc 或其他方式来创建可以放置Node 的内存。鉴于 linux 内核有这样的说法,段错误也绝对是一个问题:segmentation fault (core dumped)new_node.set_prev(*top) 行处@
  • 编译没有错误仅仅意味着语法是正确的。不过,这与逻辑是否正确无关。这是您学习使用调试器单步执行代码的最佳时机,这样您就可以跟踪执行路径并查看发生了什么以及您的逻辑哪里出错了。
  • 不能在不了解new之前安全地使用它。

标签: c++ stack


【解决方案1】:

显示的代码中存在多个与指针和对象在 C++ 中的工作方式有关的基本错误。这不仅仅是一个问题或错误,所有这些问题都必须在它正常工作之前得到解决。

Node* prev;

这是Node 类的指针成员。在使用指针引用的对象之前,必须将指针设置为指向有效对象。

显示的代码中似乎没有将prev 设置为指向任何有效的Node 对象。

void set_prev(Node nd){
            *prev=nd;
}

这会将一个对象分配给prev 指针所引用的对象。 prev 指针从未被初始化为指向任何地方的任何对象。因此它的值是未初始化的随机垃圾。分配给由随机的、未初始化的垃圾指针引用的对象是未定义的行为,并且几乎可以保证崩溃。

很明显,通过检查其余代码,这里的意图是将 指针 传递给另一个 Node 对象,而不是 @987654330 @对象本身;然后将prev指针设置为传入的指针值。

        Node new_node(x);
        new_node.set_prev(*top);

因此,在这里,应该使用指向new_node 的指针调用set_prev(),而不是将其(的副本)传递给set_prev()。然而,问题远未结束。 new_node 是在自动范围内声明的对象。此函数返回后,new_node 被销毁。任何指向它的现有指针现在都指向一个已破坏的、不再有效的对象,并且取消引用它会进一步导致未定义的行为,并且很可能会导致另一个崩溃。

很明显,根据上下文,这里的意图是使用new 关键字在动态范围内实例化一个新的Node 对象。因此,pop() 也应该是 delete 他们。

这种家庭作业传统上是在引入动态范围的概念后给出的,并使用newdelete在动态范围内创建对象。您应该查看您的课堂笔记或教科书资料,以获取有关此主题的更多信息,以及有关如何正确、正确地创建和销毁对象的更多详细信息;以及正确使用指针。

【讨论】:

  • 实际上,我在学校从来没有学过 C++,只是想尝试编写一个堆栈来学习一些东西。感谢您非常详细的回答!
  • C++ 是当今使用的最复杂、最难学习的通用编程语言。不要在网站或 Youtube 视频上浪费时间。任何小丑都可以为他们的意识流创建一个网站,或者将漫无边际的视频上传到 Youtube。你不会从中学习 C++。如果你想继续学习see Stackoverflow's list of C++ textbooks.
猜你喜欢
  • 2015-07-30
  • 2019-05-09
  • 1970-01-01
  • 2021-11-25
  • 2019-03-29
  • 2011-08-13
  • 2014-05-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多