c++ - 链表打印意外值

标签 c++ class object linked-list

无论我检查了多少引用文献,我总是发现我的实现是正确的。 但是,这段程序不起作用,我不知道为什么。 请帮忙。谢谢。 我有这门课

class intNode
{
    int x;
    intNode * next;
    public:
        intNode();
        intNode(int y, intNode *p);
        setNode(int y, intNode *p);
        int getX();
        void setX(int y);
        void setNext(intNode *p);
        intNode* getNext();
};

和这个类

class intList
{
    private:
       intNode * head;
    public:
       intList(); //sets head=NULL
       void push( int x);
       void print();
 }

推送如下

      void intList::push(int x)
      {
        intNode *newNode;
        newNode->setX(x);
        newNode->setNext(head);
        head = newNode;
      }

打印如下

void intList::print()
{
    intNode *current = head;
    cout << "Printing list" << endl;
    while(current != NULL)
    {
        cout << current->getX() << "\t";
        current = current->getNext();
    }
    cout << endl;
}

但不知何故,这段代码在main

intList l;
l.push(5);
l.print();

返回这个奇怪的值:6946556

最佳答案

让我们检查一下您的 push 方法,看看哪里出了问题。

intNode *newNode;

您现在有一个名为 newNode 的变量,它是指向 intNode 的指针。 该指针当前未设置为任何值(我们称之为“未初始化”)。

尝试访问未初始化的变量(例如取消引用它或调用它的方法)会导致 undefined behavior ,这是另一种说法“所有赌注都取消了”——标准没有说明应该发生什么,所以你的编译器可以生成它想要的任何东西。

所以当你这样做的时候:

newNode->setX(x);

您现在正在调用未初始化指针 newNode 上的方法。除此之外的任何事情都与我们检查代码无关,因为编译器在优化程序时可能会无意中做出许多看似“疯狂”的事情。

例如,您的程序在 g++ 6.4.0-O0 上对我来说运行良好。它打印 5。这是因为编译器没有优化任何东西,我们显然“幸运”并且 newNode“恰好是”的值实际上是一个有效地址。

但是,当我转到-O1 时,程序实际上根本没有输出任何值。我怀疑编译器识别出 push 在所有代码路径上导致 UB,因此得出结论绝不能调用 push,并且根本不会生成任何程序集对于这个方法。 (注意:此时我没有在程序集中对此进行验证。)

这只是调用未定义行为时发生的疯狂事情之一 - 请参阅上面链接的其他文章。未定义的行为应该永远不会发生在您的代码中。

现在,这里正确的做法是分配一个节点并设置指针指向它。初始化它

intNode *newNode = new intNode();

,那么你的代码看起来没问题。不要忘记 new 是一个堆分配 - 你的工作是确保它在不再需要时被 deleted(当你删除节点时),否则你会有未被使用的杂散内存(memory leak)。

PS:如果你用-Wall选项调用g++,它会警告你这个错误:

test.cpp: In member function ‘void intList::push(int)’:
test.cpp:30:17: warning: ‘newNode’ is used uninitialized in this function [-Wuninitialized]
 newNode->setX(x);

始终注意编译器警告 - 通常有充分的理由!

关于c++ - 链表打印意外值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47222315/

相关文章:

class - 断开模块脚本与本地脚本的连接

class - `Class of `类型声明的含义是什么?

c++ - C++ 中的递归与迭代阶乘

c++ - 使用节点类

c++ - 如何从 char 数组中删除前 4 个字符

python - "Friend"在 python 中学习类

javascript - 将javascript对象转换为css样式时出现问题

java - 为什么它不交出我的东西?

c - 人们使用什么技术/策略在 C(不是 C++)中构建对象?

c++ - 条件变量的 "wait"函数在提供谓词时导致意外行为