我有Segmentation fault (core dumped)
错误。
main.c
#include "header1.h"
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv) {
struct t_list *list = NULL;
doFill(list);
printf("%sn", list->name);
free(list);
return 0;
}
头1.h
#ifndef HEADER1_H
#define HEADER1_H
struct t_list {
char *name;
struct t_list *next;
};
void doFill(struct t_list *list);
#endif
工人.c
#include "header1.h"
#include <stdlib.h>
void doFill(struct t_list *list) {
list = (struct t_list *) malloc(sizeof(struct t_list));
char *tmp = "somename";
list->name = tmp;
list->next = NULL;
}
当我运行这个(gcc -g main.c worker.c -o test
)时,我得到(在main.c中有printf
的行上):
Segmentation fault (core dumped)
在gdb
中,我看到:
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffddf8) at main.c:8
8 struct t_list *list = NULL;
(gdb) next
9 doFill(list);
(gdb) step
doFill (list=0x0) at worker.c:6
6 list = (struct t_list *) malloc(sizeof(struct t_list));
(gdb) p list
$1 = (struct t_list *) 0x0
(gdb) next
7 char *tmp = "somename";
(gdb) p list
$2 = (struct t_list *) 0x0
如您所见,worker.c中的malloc
没有为list
变量分配内存(malloc
前后的指针指向0x0
)。
如果我在main.c中从doFill
过程中移动代码,它会正确工作:
main.c
#include "header1.h"
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv) {
struct t_list *list;
list = (struct t_list *) malloc(sizeof(struct t_list));
char *tmp = "somename";
list->name = tmp;
list->next = NULL;
printf("%sn", list->name);
free(list);
return 0;
}
$ gcc -g main.c -o test
$ ./test
somename
这怎么可能?我做错了什么?
gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)
您没有收到list
的新值。事实上,传入list
是完全无用的。此节点最好传入name
。
typedef struct t_list List;
List *newListNode(char *name) {
List *list = malloc(sizeof(*list));
if (!list) return NULL;
list->name = strdup(name);
if (!list->name) { free(list); return NULL; }
list->next = NULL;
return list;
}
char *strdup(char *src) { // if strdup doesn't already exist.
char *dst = malloc(strlen(src) + 1);
if (!dst) return NULL;
strcpy(dst, src);
return dst;
}
要将节点添加到列表的前面:
List *listAdd(List *list, char *name) {
List *newnode = newListNode(name);
if (!newnode) return NULL;
if (list) newnode->next = list;
return newnode;
}
要删除列表,请记住删除malloc
ed字符串:
void deleteList(List *list) {
for (List *next; list; list = next) {
next = list->next;
free(list->name);
free(list);
}
}
C中的参数是通过副本传递的。您在doFill()
中对list
所做的更改不会传播回main()
,这意味着list
在main()
中始终是NULL
。尝试将指针传递给指针:
#include "header1.h"
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv) {
struct t_list *list = NULL;
doFill(&list);
printf("%sn", list->name);
free(list);
return 0;
}
然后相应地更改doFill()
:
#include "header1.h"
#include <stdlib.h>
void doFill(struct t_list **list) {
*list = malloc(sizeof(**list));
char *tmp = "somename";
(*list)->name = tmp;
(*list)->next = NULL;
}