我正在编写一个Snake游戏,这是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-> head设置为新地址。
snake->head = snake->body;
关于c - 尝试重新分配内存时出现“大小为4的无效读取”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57840896/