c - "Invalid read of size 4"尝试重新分配内存时

标签 c valgrind

我正在编写一个贪吃蛇游戏,作为 C 语言中的第一个“严肃”项目。但是当我尝试培育贪吃蛇时,程序因 SEGFAULT 错误而崩溃。 所以,我尝试在 Valgrind 中运行游戏,并得到了这个:

==11312== 30 errors in context 7 of 7:
==11312== Invalid read of size 4
==11312==    at 0x10969E: collide (game.c:238)
==11312==    by 0x108FBD: main (game.c:120)
==11312==  Address 0x5897c60 is 0 bytes inside a block of size 40 free'd
==11312==    at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11312==    by 0x109724: snake_grow (game.c:250)
==11312==    by 0x108F7D: main (game.c:113)
==11312==  Block was alloc'd at
==11312==    at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11312==    by 0x109278: start (game.c:159)
==11312==    by 0x108EC0: main (game.c:91)
==11312== 
==11312== ERROR SUMMARY: 80 errors from 7 contexts (suppressed: 0 from 0)

正如我所说,我重新分配错误,这就是游戏崩溃的原因。所以,问题应该出在这里:

void snake_grow(snake_t *snake){
  snake->length++;
  snake->body = realloc(snake->body, sizeof(snake->body[0]) * (snake->length));
  snake->end = snake->body + snake->length - 1;
  snake->end->x = snake->prev_x;
  snake->end->y = snake->prev_y;
}

或者也许我只是在函数中使用了错误的指针?

bool collide(snake_t *snake, block map[MAXY][MAXX]){
  bool ret = FALSE;
  if(map[snake->head->y][snake->head->x].collision == COLLIDABLE){
    ret = TRUE;
  }
  for(int i = 1; i < snake->length; i++){
    if(snake->body[i].x == snake->head->x){
      if(snake->body[i].y == snake->head->y){
    ret = TRUE;
      }
    }    
  }
  return ret;
}

奇怪,但我找不到与我的问题类似的东西。但也许我只是不理解解决方案。

最佳答案

意外地,当我尝试制作最小的可重现示例并进行调试时,正如 WhozCraig 的建议,我解决了这个问题。

void snake_grow(snake_t *snake){
  snake->length++;
  snake->body = realloc(snake->body, sizeof(snake->body[0]) * (snake->length));
  snake->end = snake->body + snake->length - 1;
  snake->end->x = snake->prev_x;
  snake->end->y = snake->prev_y;
}

该函数除了重新分配内存外,还为snake->end设置新的地址。但还有snake->head,它在realloc之后指向相同的地址。所以,我需要做的就是将snake->head 设置为新地址。

snake->head = snake->body;

关于c - "Invalid read of size 4"尝试重新分配内存时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57840896/

相关文章:

C getline() 在 EOF 之前返回 -1

c - 在 C 中实现列表 - 将结构作为右值传递给函数

连接键盘输入的两个字符串

c - C中Valgrind的解读

c++ - 空文件中的 Valgrind C++ 内存泄漏

c - 为什么我的 if 语句从未被评估过?

c - 如何防止 C 预处理器宏扩展为重复值?

valgrind - FreeBSD 上 valgrind 的限制

c - 大小为 1 X 字节的无效写入 **在大小 >X **分配**的 block 内**

c - Valgrind:禁用条件跳转(或整个库)检查