微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C realloc:下一个大小无效,aSan表示释放后使用堆

如何解决C realloc:下一个大小无效,aSan表示释放后使用堆

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

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

我通过执行Coord* snakeArr = malloc(2 * sizeof(Coord));并使用int snakeArrSize = 2;跟踪数组的大小来使用Coords数组。我已经将此函数模仿了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;
}

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

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]超出范围,您不能使用它来存储内容。

循环

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

应该是

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。