C realloc:下一个大小无效,aSan 说 heap-use-after-free

C realloc: invalid next size, aSan says heap-use-after-free

如果这是一个重复的问题,我很抱歉,但我查看了其他各种答案,但它们似乎不适用于我的代码。
我定义了一个结构 Coord,它只是一个 x 和 y,每个限制为 4 位。

typedef struct {
    unsigned int x:4;
    unsigned int y:4;
} Coord;

我通过执行 Coord* snakeArr = malloc(2 * sizeof(Coord)); 并使用 int snakeArrSize = 2; 跟踪数组的大小来使用坐标数组。我做了这个函数来模仿 unshift() javaScript 函数。

void unshiftCoord(Coord *arr, Coord value, int *arrSize) {
  // Debugging
  printf("%li\n", (*arrSize + 1) * sizeof(Coord));
  fflush(stdout);

  // Allocate an extra slot in the array
  arr = realloc(arr, (*arrSize + 1) * sizeof(Coord));

  // Shift everything over
  for (int i = *arrSize; i > 0; i--) {
    arr[i] = arr[i - 1];
  }

  // Set the first value in the array
  arr[0] = value;
  // Update arrSize variable
  *arrSize += 1;
}

这工作得很好,但由于某种原因,当我第 5 次调用该函数时,它给出了“下一个尺寸无效”错误。这是我的程序的输出:

12
16
20
24
28
realloc(): invalid next size
Aborted (core dumped)

如您所见,当新大小增加到 28 时,realloc() 失败。
我遇到的一种解决方案是使用 aSan。我在我的编译器标志中使用 -fsanitize=address 完成了此操作,当我 运行: ERROR: AddressSanitizer: heap-use-after-free... 和一条非常长的消息时,我做对了。需要的话我放在this google doc.

成功后

  arr = realloc(arr, (*arrSize + 1) * sizeof(Coord));
  *arrSize += 1;

arr*arrSize 元素,所以 arr[*arrSize] 是 out-of-range,你不能用它来存储东西。

循环

  for (int i = *arrSize; i > 0; i--) {

应该是

  for (int i = *arrSize - 1; i > 0; i--) {

还应检查 realloc() 的结果以避免取消引用 NULL

还有一个关键点:参数arr已传递内容的副本,因此对其进行修改不会影响已传递内容。因此,如果 realloc() returns new buffer,它会丢失,原始无效的 arr 将在后面的过程中使用。 为避免这种情况,应传递指向变量的指针而不是 arr,并且应通过指针修改变量。