I have the Segmentation fault (core dumped)
error.
我有分段错误(core dump)错误。
main.c
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
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
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;
}
When I run this (gcc -g main.c worker.c -o test
) I get (on the line with printf
in main.c):
当我运行这个(gcc -g main)时。c工人。c -o测试)我得到(在main.c中与printf一致):
Segmentation fault (core dumped)
In gdb
I see:
在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
As you can see malloc
in worker.c doesn't allocate memory for the list
variable (the pointer before and after malloc
points at 0x0
).
正如你在工作中看到的malloc。c不为列表变量分配内存(在0x0中malloc点之前和之后的指针)。
If I move the code from the doFill
procedure in main.c it works correctly:
如果我把代码从主要的doFill过程中移动。c它工作正常:
main.c
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
How is it possible? What do I do wrong?
怎么可能?我做错了什么?
gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)
2 个解决方案
#1
1
Parameters in C are passed by copy. The changes you make to list
inside of doFill()
are not propagated back to main()
, which means that list
is always NULL
in main()
. Try passing a pointer to pointer instead:
C中的参数通过copy传递。在doFill()中列出的更改不会传播回main(),这意味着列表在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("%s\n", list->name);
free(list);
return 0;
}
And then change doFill()
accordingly:
然后相应地改变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;
}
#2
2
You aren't receiving back the new value of list
. In fact, passing list
in is totally useless. Better to pass in the name
for this node.
您没有收到新的列表值。事实上,通过列表是完全没用的。最好将这个节点的名称传递给它。
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;
}
To add nodes to the front of the list:
将节点添加到列表的前面:
List *listAdd(List *list, char *name) {
List *newnode = newListNode(name);
if (!newnode) return NULL;
if (list) newnode->next = list;
return newnode;
}
To delete the list, remember to delete the malloc
ed strings:
要删除列表,请记住删除malloced字符串:
void deleteList(List *list) {
for (List *next; list; list = next) {
next = list->next;
free(list->name);
free(list);
}
}
#1
1
Parameters in C are passed by copy. The changes you make to list
inside of doFill()
are not propagated back to main()
, which means that list
is always NULL
in main()
. Try passing a pointer to pointer instead:
C中的参数通过copy传递。在doFill()中列出的更改不会传播回main(),这意味着列表在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("%s\n", list->name);
free(list);
return 0;
}
And then change doFill()
accordingly:
然后相应地改变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;
}
#2
2
You aren't receiving back the new value of list
. In fact, passing list
in is totally useless. Better to pass in the name
for this node.
您没有收到新的列表值。事实上,通过列表是完全没用的。最好将这个节点的名称传递给它。
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;
}
To add nodes to the front of the list:
将节点添加到列表的前面:
List *listAdd(List *list, char *name) {
List *newnode = newListNode(name);
if (!newnode) return NULL;
if (list) newnode->next = list;
return newnode;
}
To delete the list, remember to delete the malloc
ed strings:
要删除列表,请记住删除malloced字符串:
void deleteList(List *list) {
for (List *next; list; list = next) {
next = list->next;
free(list->name);
free(list);
}
}