蛇形程序数组值异常变更问题求助
问题:贪吃蛇程序数组值莫名变更
我正在开发一款简易贪吃蛇程序,发现数组中的值出现莫名变更。已尝试通过网络搜索及代码排查寻找原因但未解决,恳请告知问题原因及修复方案。
代码部分
Game.c
#include "hardware.h" #include "paint.h" // Include the library of paint functions #include "snake.h" // Include the library of snake functions #include <stdbool.h> #include <stdio.h> #include <time.h> #include <unistd.h> // Set paint's size parameters to be equal to the snake ones const int NCOLS = X_SIZE; const int NROWS = Y_SIZE; // Variables for game speed #define START_WAIT 0.5 // #define SPEEDUP_FACTOR 0.9 int main() { snake_t snakey; apple_t appley; appley.x = 12; appley.y = 12; int world[NROWS][NCOLS]; snake_init(&snakey); world_field(world, &appley, &snakey); image_print(world); return 0; }
Snake.h
#include "paint.h" #include <stdio.h> #include <stdbool.h> #include <stdlib.h> #ifndef __SNAKE_H__ #define __SNAKE_H__ // For snake we define the size by these macros // Here the two dimensions are called x and y #define X_SIZE 80 // Horizontal size, including walls #define Y_SIZE 20 // Vertical size, including walls typedef struct { int x, y; } apple_t; typedef enum { UP, RIGHT, DOWN, LEFT } dir_t; typedef struct { int x[(X_SIZE - 2) * (Y_SIZE - 2)]; int y[(X_SIZE - 2) * (Y_SIZE - 2)]; int length; dir_t dir; } snake_t; void world_field(int world[Y_SIZE][X_SIZE], apple_t *apple, snake_t *snake); void snake_init(snake_t *snake); void world_field(int world[Y_SIZE][X_SIZE], apple_t *apple, snake_t *snake) { for (int row = 0; row <= Y_SIZE; row++) { for (int col = 0; col <= X_SIZE; col++) world[row][col] = GRASS; } add_rectangle(world, WALL, 0, 0, X_SIZE - 1, Y_SIZE); world[snake->y[0]][snake->x[0]] = SNAKE_HEAD; for (int i = 0; i < snake->length; i++) { world[snake->y[i]][snake->x[i]] = SNAKE_BODY; printf("Snake X 0: %d\nSnake Y 0: %d\nSnake X 1: %d\nSnake Y 1: %d\n", snake->x[0], snake->y[0], snake->x[1], snake->y[1]); } } void snake_init(snake_t *snake) { snake->dir = RIGHT; snake->length = 2; for (int i = 0; i < ((X_SIZE - 2) * (Y_SIZE - 2)); i++) { snake->x[i] = 90; snake->y[i] = 90; } snake->x[0] = 40; snake->x[1] = 39; snake->y[0] = 10; snake->y[1] = 10; printf("X koordinate 0: %d\nY koordinate 0: %d\n X koordinate 1: %d\n Y koordinate 1: %d\n\n\n\n", snake->x[0], snake->y[0], snake->x[1], snake->y[1]); } #endif
输出情况
snake_init()函数输出:
X koordinate 0: 40
Y koordinate 0: 10
X koordinate 1: 39
Y koordinate 1: 10
world_field()函数输出:
Snake X 0: 46
Snake Y 0: 10
Snake X 1: 46
Snake Y 1: 10
问题原因
核心是数组越界访问破坏了相邻内存:
world_field里的数组初始化循环用了row <= Y_SIZE和col <= X_SIZE,但world数组只有Y_SIZE行、X_SIZE列,合法索引范围是0到Y_SIZE-1、0到X_SIZE-1。越界访问会覆盖world数组后面的内存区域,而snakey变量正好存储在这个区域,导致蛇的坐标被篡改。add_rectangle调用的最后一个参数是Y_SIZE,超出了数组行索引的最大值Y_SIZE-1,如果函数内部访问这个索引,会进一步加重内存破坏。
修复方案
- 修正数组初始化循环的边界:
把循环条件改成< Y_SIZE和< X_SIZE,确保只访问合法索引:
for (int row = 0; row < Y_SIZE; row++) { for (int col = 0; col < X_SIZE; col++) world[row][col] = GRASS; }
- 修正
add_rectangle的参数:
将最后一个参数改为Y_SIZE - 1,符合数组行索引范围:
add_rectangle(world, WALL, 0, 0, X_SIZE - 1, Y_SIZE - 1);
- (可选)优化蛇身初始化:
snake_init里给所有蛇身元素赋值90的循环没必要,初始长度只有2,只初始化前2个元素即可:
void snake_init(snake_t *snake) { snake->dir = RIGHT; snake->length = 2; snake->x[0] = 40; snake->x[1] = 39; snake->y[0] = 10; snake->y[1] = 10; printf("X koordinate 0: %d\nY koordinate 0: %d\n X koordinate 1: %d\n Y koordinate 1: %d\n\n\n\n", snake->x[0], snake->y[0], snake->x[1], snake->y[1]); }
内容的提问来源于stack exchange,提问作者user17093173
相关产品推荐
相关产品推荐

