2014-11-09 4 views
0

나는 Segmentation fault (core dumped) 오류가 있습니다.Malloc이 구조체에 메모리를 할당 할 수 없습니다.

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와 라인에 (얻을 : gdb에서

Segmentation fault (core dumped) 

내가 참조 :

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) 
+3

'무효 doFill (구조체 t_list :

List *listAdd(List *list, char *name) { List *newnode = newListNode(name); if (!newnode) return NULL; if (list) newnode->next = list; return newnode; } 

이 목록을 삭제 malloc 에드 문자열을 삭제하는 것을 기억하기 :

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)'호출자가 할당을 볼 수있게하려면'**'가 필요합니다. –

+0

[malloc (및 친구들)의 결과를 캐스팅하지 마십시오] (http://stackoverflow.com/q/605845). – Deduplicator

+0

@Deduplicator 링크를 가져 주셔서 감사합니다. C 언어의 제작자가 저술 한 'The C Programming Language'책을 읽었습니다.그들은 malloc의 결과를 캐스팅했습니다. 나는 역시 캐스팅합니다. 그러나이 책은 1988 년에 쓰여졌 고, 나는 이미 쓸모없는 행동이었을 것이라는 데 동의한다. – zaratustra

답변

1

C의 매개 변수는 copy에 의해 전달됩니다. 의 변경 내용이 doFill() 인 경우 main()으로 전파되지 않으므로 list은 항상 NULLmain()입니다.

#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; 
} 
+1

고마워, 친구, 잘됐다. – zaratustra

2

을 당신은 list의 새 값을 다시 수신되지 않습니다. 실제로 list을 전달하면 전혀 쓸모가 없습니다. 이 노드에 대해 name을 전달하는 것이 좋습니다. *

void deleteList(List *list) { 
    for (List *next; list; list = next) { 
    next = list->next; 
    free(list->name); 
    free(list); 
    } 
} 
관련 문제