我在上面带有这些函数的结构。目的是模仿使用预分配数组的列表存储/访问。
#define ALLOC_INC_COUNT 100
typedef struct
{
size_t count, el_size, alloc_count;
char data[];
} bl_t;
bl_t *bl_new(size_t el_size)
{
bl_t *list = malloc(sizeof *list + ALLOC_INC_COUNT * el_size);
if (list == NULL)
return NULL;
list->count = 0;
list->el_size = el_size;
list->alloc_count = ALLOC_INC_COUNT;
return list;
}
我的问题是,如果我想使用类似bl_add()的函数来调整结构的大小,那么在重新分配结构后,程序在memcpy行上的功能将不正确。我不太清楚为什么。
bool bl_add(bl_t *list, void *data)
{
if (list->count > list->alloc_count - 1)
{
bl_t *swap = realloc(list, sizeof *swap + (list->count + ALLOC_INC_COUNT) * list->el_size);
if (swap == NULL)
return 0;
list = swap;
list->alloc_count += ALLOC_INC_COUNT;
}
memcpy(list->data + list->count * list->el_size, data, list->el_size);
list->count++;
return 1;
}
这里的问题是,bl_add
可以重新分配作为参数传递的bl_t*
,但是它无法通知调用方它已经这样做了,或者该参数的新值应该是什么。因此,调用者的list
变成了一个悬空的指针,下次使用它时,将会出现混乱(也称为未定义的行为)。
一种解决方案是返回新的list
值(或在失败的情况下返回NULL
,要求调用者编写:
list = bl_add(list, data);
另一种可能性是要求调用者将pointer传递给list
指针(“句柄”,从而允许bl_add
更新指针:]]
status = bl_add(&list, data);