0

我编写了以下代码,仅在 C++ 中创建节点(整数数据)并将其插入到 SLL 中。

#include <stdio.h>

class Node
{
    public:
        int data;
        Node * next;
        Node * first;
        Node() {}

        void insert(int dat)
        {
            Node * newnode = new Node();
            newnode->data=dat;
            newnode->next=NULL;
            if(first==NULL)
            {
                first=newnode;
            }
            else
            {
                Node *temp=first;
                while(temp->next!=NULL)
                { temp=temp->next; }
                temp->next=newnode;
            }
        }
};

int main()    
{
    Node * a=new Node();
    a->insert(12);
    return 0;
}

起初,我尝试将 Node 构造函数重写为 Node(int dat),并尝试对我在插入中创建的每个新节点 (data=dat, next=NULL) 进行初始化。将使用 main 中的“dat”值调用 Insert,它会调用重载的 Node 构造函数以将数据初始化为 dat 和 NULL 旁边。这导致我的程序崩溃。

所以我取出了默认和重载的构造函数,并对插入本身的每个新元素进行了初始化。我的程序运行良好。但是,即使添加了默认构造函数(如代码的第 10 行所示),我的程序也会崩溃。谁能告诉我为什么这两种情况都会发生?

谢谢。

4

3 回答 3

1

您的默认构造函数使数据成员未初始化。所以这一行:

Node * a=new Node();

创建一个具有未初始化成员的节点,当您尝试添加节点时会导致问题。当您删除默认构造函数时,上述行(由于双亲new Node()以及该类没有用户定义的构造函数的事实)导致所有成员的值初始化,因此指针被初始化为NULL,并且您得到预期的行为。

如果你没有留下括号:

Node * a = new Node;

数据成员将未初始化,就像您有一个什么都不做的默认构造函数一样。

正确的解决方案是修复默认构造函数以显式初始化所有成员。

Node() :data(0), next(nullptr), first(nullptr) {}
于 2013-10-28T06:37:01.217 回答
0
Node * a=new Node();

创建一个新节点,运行其默认构造函数...

Node() {}

...这没有多大作用 - 甚至没有初始化data,nextfirst.

因此,当您调用...

a->insert(12);

......它尝试......

if(first==NULL)

...它从未初始化的内存中读取,导致未定义的行为。在一次运行中,新创建的对象可能碰巧在其中有一个 0,另一次可能没有,另一次它可能会在尝试读取值时崩溃。你继续用未初始化的数据做其他更糟糕的事情。

更一般地说,当您遇到此类问题时,我建议您放入std::cerr << xyz << '\n';语句以转储一些相关变量,或在调试器中进行跟踪 - 您可能已经看到变量具有垃圾值,然后可能已经开始调查原因,这可能有在这里产生了一个更集中的问题,或者可能引导你找到一个现有的答案......

于 2013-10-28T06:38:36.180 回答
0

像这样在构造函数中初始化成员变量

Node() {
             data =0;
             first = NULL;
             next = NULL;
}
于 2013-10-28T07:28:13.953 回答