c-Malloc无法为结构分配内存



我有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(),这意味着listmain()中始终是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;
}

相关内容

  • 没有找到相关文章

最新更新