首页 > 解决方案 > C realloc:下一个大小无效,aSan 说 heap-use-after-free

问题描述

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

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

我正在使用 Coords 数组,方法是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......和一个非常长的消息。如果你需要它,我把它放在这个 google doc中。

标签: creallocaddress-sanitizer

解决方案


成功后

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

arr*arrSize元素,所以arr[*arrSize]超出范围,你不能用它来存储东西。

循环

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

应该

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

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

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


推荐阅读