使用可调整大小的数组初始化列表结构的正确方法

时间:2017-10-23 20:01:26

标签: c pointers memory-management struct malloc

我有一个结构的初始化,我一直得到segmentation fault: 11

typedef struct {
    int id;
    double value;
    char* name;
} Item;

typedef struct {
    Item** items;
    int length;
    int capacity;
} List;

List* initList()
{
    List* list = NULL;
    list->items = (Item**)malloc(10 * sizeof(Item*));
    list->length = 0;
    list->capacity = 10;
    return list;
}

这里main.c是每个GDB收到错误的地方:

List* list = initList();

我无法初始化,我注意到因为

存在问题
list->items = (Item**)malloc(10 * sizeof(Item*));

我是C新手,但我确信我的initList函数会创建一个包含给定作业的列表。我还有一个相应的功能来释放items中的initList

2 个答案:

答案 0 :(得分:1)

问题在于:

List* list = NULL;
list->items = (Item**)malloc(10 * sizeof(Item*));

您使用list值初始化NULL,然后取消引用list而不给它另一个值。取消引用NULL指针会调用undefined behavior

您需要为list分配内存。然后你可以取消引用它:

List* list = malloc(sizeof(List *));
if (!list) {
    perror("malloc failed");
    exit(1);
}
list->items = malloc(10 * sizeof(Item*));
if (!list->items) {
    perror("malloc failed");
    exit(1);
}

另请注意you shouldn't cast the return value of malloc,并且不要忘记检查错误。

答案 1 :(得分:1)

list->items = (Item**)malloc(10 * sizeof(Item*));

右手边不是问题。问题是因为list指向NULL,因此将某些内容分配给其中一个字段未定义的行为

您可以通过返回结构而不是指针来避免此分配。无需动态分配结构,它具有固定的大小。

List initList()
{
    List list;
    list.items = malloc(10 * sizeof(Item*));
    list.length = 0;
    list.capacity = 10;
    return list;
}

呼叫者:

List list = initList();

复制开销非常小,但没有携带另一个动态分配指针的好处很大。