创建链表时出现神秘的分段错误(添加功能)

Posted

技术标签:

【中文标题】创建链表时出现神秘的分段错误(添加功能)【英文标题】:Mysterious segmentation fault while creating a Linked List (Add function) 【发布时间】:2012-06-05 19:38:01 【问题描述】:

我试图在 C 中创建一个链接列表,但由于一些神秘的错误,程序崩溃了。

首先我尝试了这个:

typedef struct product_data product_data;

struct product_data 
 int product_code;
 int product_size;
 product_data *next;
;

product_data *products_head = NULL;
product_data *products_tail = NULL;

int main() 
    int newcode = 5;
    int newsize = 5;
    products_head->product_code = newcode;
    products_head->product_size = newsize;
    products_head->next = NULL;

    return 0;

不幸的是,程序在没有任何错误消息的情况下崩溃。

然后我改变了一些部分:

typedef struct product_data product_data;

struct product_data 
 int product_code;
 int product_size;
 product_data *next;
;

product_data *products_head = NULL;
product_data *products_tail = NULL;

int main() 
    product_data *newproduct;
    int newcode = 5;
    int newsize = 5;
    newproduct->product_code = newcode;
    newproduct->product_size = newsize;
    newproduct->next = NULL;

    products_head = newproduct;

    return 0;

这次没有崩溃,它似乎工作。我不知道为什么。

有什么想法吗?

提前致谢!

【问题讨论】:

必须是最近的家庭作业... 不得不让你失望——没有作业。 ;-) 不幸的是我不再那么年轻了...... 没有侮辱的意思;这些问题有时只是“批量”出现:-) 【参考方案1】:

它真的不起作用。您仍在取消引用无效指针:

product_data *newproduct;
int newcode = 5;
int newsize = 5;
newproduct->product_code = newcode;
newproduct->product_size = newsize;
newproduct->next = NULL;

但是,虽然在第一个版本中您要取消引用显式设置为 NULL 的指针,但它会因应有的​​分段错误而崩溃。在这里,您正在取消引用一个包含堆栈上任何数据的指针,不幸的是它不会崩溃。这是未定义的行为,因此不一定会崩溃。

你必须让你的指针指向有效的内存,

newproduct = malloc(sizeof product_data);

【讨论】:

【参考方案2】:

您需要为 products_head 分配内存。现在,您只需将其设置为 NULL。要么不要让它成为指针,要么使用 malloc。

【讨论】:

【参考方案3】:

在您的第一个示例中,您正在写入一个 NULL 指针。在取消引用之前,您需要为 products_head 分配空间。类似的东西

products_head = malloc(sizeof(product_data));

我不知道为什么您的第二个示例有效。它不应该。 newproduct 是一个未初始化的变量,它可以指向任何地方。也许你只是走运了,它指向了一块未使用的有效内存。

【讨论】:

【参考方案4】:

这将一直有效,直到它不起作用为止。您仍然没有为您的结构分配任何内存。但是由于一些运气,newproduct 指向了一些有效的内存位置。您面临的问题是 product_head 被手动设置为 null (即使这不是必需的,因为所有全局变量总是被初始化)。然而堆栈变量并没有被初始化,你很幸运(或者很不幸,它会导致你错过一个明显的编程错误)它恰好指向你地址空间中的某个有效位置。

您可以使用 printf("%p", newproduct); 打印 newproduct 的内容以查看它指向的位置不幸的是,插入这一行可能会改变程序的行为。

【讨论】:

【参考方案5】:

“->”用于访问动态分配的结构中的元素,“.”用于访问静态分配的结构中的元素。

这是一个例子:

typedef struct product_data product_data;

struct product_data 
    int product_code;
    int product_size;
    product_data *next;
;

product_data *products_head = NULL;
product_data *products_tail = NULL;

int main() 
    /* Allocate memory */
    product_data *newproduct = malloc(sizeof(product_data));
    int newcode = 5;
    int newsize = 5;

    products_head = newproduct;
    newproduct->product_size = newsize;
    newproduct->next = NULL;

    /* free memory */
    free(product_data);

    return 0;

但请记住,对于您在链表中创建的所有新节点,您必须分配内存并释放该内存。用于检查您分配的所有内存是否已释放的好程序是 valgrind。如果你在尝试让链表先手动绘制它时遇到逻辑错误,如下所示:

      [head]   [tail]
        |        |
        V        V
      [ a ] -> [ b ] -> null

请记住 head 和 tail 都是指针(因此它们不需要分配内存,它们只需要指向您想要的节点即可。

如果您仍然遇到问题,因为您的逻辑变得非常复杂,我建议您尝试学习 GDB(它是一个命令行调试器),它将帮助您逐步执行代码,以便您可以逐步了解正在发生的事情。这就是我第一次学会创建数据结构的方式。

祝你好运!

【讨论】:

以上是关于创建链表时出现神秘的分段错误(添加功能)的主要内容,如果未能解决你的问题,请参考以下文章

链表:将值分配给节点的下一部分时出现分段错误错误

呈现窗口时出现 Gtkmm 分段错误

分段错误:在 C++ 中弹出向量时出现 11

添加指向数组的指针时出现分段错误

在 C++ 中比较来自向量的字符串时出现分段错误

访问共享内存时出现分段错误