You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

蛇形程序数组值异常变更问题求助

问题:贪吃蛇程序数组值莫名变更

我正在开发一款简易贪吃蛇程序,发现数组中的值出现莫名变更。已尝试通过网络搜索及代码排查寻找原因但未解决,恳请告知问题原因及修复方案。


代码部分

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


问题原因

核心是数组越界访问破坏了相邻内存:

  1. world_field里的数组初始化循环用了row <= Y_SIZE和col <= X_SIZE,但world数组只有Y_SIZE行、X_SIZE列,合法索引范围是0到Y_SIZE-1、0到X_SIZE-1。越界访问会覆盖world数组后面的内存区域,而snakey变量正好存储在这个区域,导致蛇的坐标被篡改。
  2. add_rectangle调用的最后一个参数是Y_SIZE,超出了数组行索引的最大值Y_SIZE-1,如果函数内部访问这个索引,会进一步加重内存破坏。

修复方案

  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;
}
  1. 修正add_rectangle的参数:
    将最后一个参数改为Y_SIZE - 1,符合数组行索引范围:
add_rectangle(world, WALL, 0, 0, X_SIZE - 1, Y_SIZE - 1);
  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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 16:34:59