可变长度数组上的C realloc()

问题描述 投票:0回答:1

我在上面带有这些函数的结构。目的是模仿使用预分配数组的列表存储/访问。

#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;
}
c realloc
1个回答
0
投票

这里的问题是,bl_add可以重新分配作为参数传递的bl_t*,但是它无法通知调用方它已经这样做了,或者该参数的新值应该是什么。因此,调用者的list变成了一个悬空的指针,下次使用它时,将会出现混乱(也称为未定义的行为)。

一种解决方案是返回新的list值(或在失败的情况下返回NULL,要求调用者编写:

 list = bl_add(list, data);

另一种可能性是要求调用者将pointer传递给list指针(“句柄”,从而允许bl_add更新指针:]]

 status = bl_add(&list, data);
© www.soinside.com 2019 - 2024. All rights reserved.