我有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("%s\n", list->name);
free(list);
return 0;
}
那么header1.h
#ifndef HEADER1_H
#define HEADER1_H
struct t_list {
char *name;
struct t_list *next;
};
void doFill(struct t_list *list);
#endif
worker.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("%s\n", list->name);
free(list);
return 0;
}
$ gcc -g main.c -o test
$ ./test
somename
怎么可能?我做错了什么?
gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)
答案 0 :(得分:2)
您没有收到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);
}
}
答案 1 :(得分:1)
C中的参数通过复制传递。您在list
内对doFill()
所做的更改不会传播回main()
,这意味着list
中的NULL
始终为main()
。尝试将指针传递给指针:
#include "header1.h"
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv) {
struct t_list *list = NULL;
doFill(&list);
printf("%s\n", 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;
}