创建链表时出现神秘的分段错误(添加功能)
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(它是一个命令行调试器),它将帮助您逐步执行代码,以便您可以逐步了解正在发生的事情。这就是我第一次学会创建数据结构的方式。
祝你好运!
【讨论】:
以上是关于创建链表时出现神秘的分段错误(添加功能)的主要内容,如果未能解决你的问题,请参考以下文章