我试图通过C中的链接列表。
列表项定义为
struct list_element {
struct list_element *next;
int value;
};
列表头定义为
struct list_head {
struct list_element *front;
struct list_element *end;
};
我试图打印这样的项目
void printList(struct list_head* head) {
if(head == NULL|| head->front == NULL) {
printf("List is empty \n");
return 0;
}
struct list_element* elm = head-> front;
int numberOfElements = 0;
while(elm != NULL) {
printf("%i", elm -> value);
printf(" ");
elm = elm -> next;
}
printf("\n");
}
这在我的Mac上在XCode和https://ideone.com上运行良好,但在Windows和http://codepad.org上会导致"分段错误"。好像是
while(elm != NULL) {
printf("%i", elm -> value);
printf(" ");
elm = elm -> next;
}
导致一些问题。似乎elm并没有指向最后一项的NULL,即使它应该。
我正在添加像这样的项目
struct list_element* list_push(struct list_head* head) {
//List head is null
if(!head) {
return NULL;
}
//Initialize list element
struct list_element* elm = malloc(sizeof(struct list_element));
if(elm == NULL) {
//Couldn't alloc memory
return NULL;
}
if(head->front) {
head->front = elm;
head->end = elm;
} else {
//List head is not null, set next elm to point to current elm
elm -> next = head -> front;
head->front = elm;
}
return elm;
}
我真的很困惑为什么相同的代码在某些地方可以使用,但在其他地方则不然。 (它适用于IDEone和XCode,它不能在Windows上使用相同的代码在Codepad和Code :: block上工作)
答案 0 :(得分:3)
对于列表的第一个元素,您必须使用ele->next
初始化NULL
,否则您将在elm = elm->next
中访问未初始化的内存以获取列表的最后一个元素。除此之外,您必须将if(head->front)
更改为if ( head->front == NULL )
。像这样调整你的代码:
struct list_element* list_push(struct list_head* head) {
if ( head == NULL )
return NULL;
struct list_element* elm = malloc(sizeof(struct list_element));
if ( elm == NULL)
return NULL;
if ( head->front == NULL) // <--------------
{
elm->next = NULL; // <---------------
head->front = elm;
head->end = elm;
}
else
{
elm->next = head->front;
head->front = elm;
}
return elm;
}
请务必使用head->front
初始化head->end
NULL
。
答案 1 :(得分:2)
问题是malloc
没有为你分配给它的内存归零。您可以手动将next
指针设置为NULL
,也可以使用calloc
分配内存,这将为您归零。它在某些环境中运行而不是在其他环境中运行的原因是,它在某些情况下会击中已经用零写入的内存,或者出于安全原因某些操作系统将为您清零内存。