我试图用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;
}
这次没有崩溃,似乎有效。我不知道为什么。
有什么想法吗?
提前感谢!
它实际上不起作用。您仍在取消引用无效指针:
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);
为products_head分配内存。现在,您只需将其设置为 NULL。要么不要让它成为指针,要么使用 malloc。
在第一个示例中,您正在写入 NULL 指针。 在取消引用之前,您需要为products_head
分配空间。 类似的东西
products_head = malloc(sizeof(product_data));
我不知道为什么你的第二个例子有效。 不应该。 newproduct
是一个未初始化的变量,它可以指向任何地方。 也许你只是很幸运,它指向了未使用的有效内存块。
这将起作用,直到它不工作。您仍然没有为结构分配任何内存。但是由于运气好,newproduct 指向一些有效的内存位置。您面临的问题product_head手动设置为 null(即使不需要这样做,因为所有全局变量始终初始化)。然而,堆栈变量没有初始化,你很幸运(或者不幸,它会导致你错过一个明显的编程错误),它恰好指向你的地址空间中的某个有效位置。
您可以使用 printf("%p", newproduct) 打印新产品的内容以查看它指向的位置;遗憾的是,插入此行可能会更改程序的行为。
"->"用于访问动态分配的结构中的元素,"." 用于访问静态分配的结构中的元素。
下面是一个示例:
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
请记住,头和尾都是指针(所以它们不需要分配内存,它们只需要指向你想要的节点。
如果您仍然遇到问题,因为您的逻辑变得非常复杂,我会让您尝试学习 GDB(它是一个命令行调试器),它将帮助您逐步完成代码,以便您可以逐步了解正在发生的事情。这就是我第一次学习创建数据结构的方式。
祝你好运!