基于指针的链表给出了分段错误

时间:2014-07-30 11:28:31

标签: c++ pointers

#include "AirlineReservationSystem.h"
struct test{
    int num;
    test* tNext;
};

int main()
{
    test* a;
    a = new test;
    a->num = 8;
    a->tNext = new test;
    test* ptr = a;
    ptr = ptr->tNext;
    ptr->num = 9;
    cout << ptr->num;
    ptr = a;

    cout << ptr->num;

    while ( ptr->tNext != NULL){
        ptr = ptr->tNext;
    }

    cout << ptr->num;

    return 0;
}

我试图理解为什么这段代码会产生分段错误。在开始时忽略包含,它什么都不做。

我非常非常新,并试图更好地理解指针和链接列表并进行一些练习但我无法看到我做错了什么。

程序本身打印前两个cout但在while语句中崩溃,这意味着必须有一些问题,如果有人可以向我解释这个问题到底是什么,我错过了什么,那就太好了。感谢。

4 个答案:

答案 0 :(得分:1)

您已初始化ptr->num = 9,但尚未将ptr->tNext初始化为任何内容。

现在让我们检查以下代码:

while ( ptr->tNext != NULL){
    ptr = ptr->tNext;
}

迭代#1:

  • 最有可能ptr->tNext != NULL,因此您输入循环并设置ptr = ptr->tNext

  • 现在ptr很可能指向无效的内存地址。

迭代#2:

  • ptr很可能指向无效的内存地址。

  • 因此,ptr->tNext最有可能产生非法内存访问。

答案 1 :(得分:1)

创建第二个测试时,不要初始化结构中的指针成员。

这意味着它指向一些不是测试实例的随机内存地址(虽然我听说有些编译器会自动指向NULL,但从未见过这个实际操作)。默认情况下,默认情况下不会清除为struct保留的内存,因此任何内容都保留在“struct”中,直到您为其他内容分配。

如果您没有为其分配新值,则在尝试取消引用内存时应用程序将会中断。

所以解决这个问题:

struct test{
    test() : tNext(NULL) {} // ADD THIS AND ...
    ~test() { if(tNext) delete tNext; } // ADD THIS AND ...
    int num;
    test* tNext;
};

int main()
{
    test* a;
    a = new test;
    a->num = 8;
    a->tNext = new test;
    test* ptr = a;
    ptr = ptr->tNext;
    ptr->num = 9;
    cout << ptr->num;
    ptr = a;

    cout << ptr->num;

    while ( ptr->tNext != NULL){
        ptr = ptr->tNext;
    }

    cout << ptr->num;

    delete a; // ADD THIS

    return 0;
}

第一行是一个构造函数,它将指针设置为NULL,这将阻止指针指向随机内存。第二行是析构函数,它将以递归方式清理嵌套结构。

答案 2 :(得分:0)

这种行为是理想的,因为您的代码将从while提供segmentation fault退出,因为最后一个节点的ptr->tNext!=NULL条件也不满足。因此,对于最后一个节点,ptr设置为垃圾值,因此当执行ptr->tNext!=NULL时,它会给出分段错误错误。

要避免这种情况,请在ptr->num = 9;

之后添加以下行
ptr->tNext = NULL;

答案 3 :(得分:0)

(1)可能你缺少tNext初始化为NULL。
尝试将您的定义更改为:

struct test{
    int num;
    test* tNext;
    test():num(0),tNext(NULL) {}    // contructor initializing the members to default values
};

(2)你不知道ptr在条件下是否为NULL,在这种情况下它可能会给出分段错误。在while()中添加对ptr的空检查,如下所示:

 while (ptr && ptr->tNext != NULL){   // ptr->tNext is executed only when ptr is valid
    ptr = ptr->tNext;
}