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

标签 c gcc struct segmentation-fault malloc

我遇到了Segmentation fault (core dumped) 错误。

ma​​in.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)。

如果我将 doFill 过程中的代码移到 main.c 中,它会正常工作:

ma​​in.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)

最佳答案

您没有收到 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;
}

要删除列表,请记住删除 malloced 字符串:

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

关于c - Malloc 无法为结构分配内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26829122/

相关文章:

c - sscanf 获取被两个固定字符串包围的字符串段

c++ - 如何在不重新编译 gcc 的情况下修改传递给 ld 的选项

在 gcc 编译的 c 程序中,表达式是否太长?

c++ - 哪些标准允许在 C 和 C++ 中使用匿名结构和 union ?

c - 如何将参数放入结构中?

c - 为什么 realloc() 在 C 中 malloc() 成功的地方失败?

c - 为什么这里会出现段错误?

c - 读取C中的汇编文件

c++ - 如何将 c/c++ 应用程序移植到旧版 linux 内核版本

c - 将 BST 传递给结构数组