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

C语言终端贪吃蛇realloc扩容触发double free or corruption错误求助

问题排查与修复方案

触发内存错误的核心原因

  1. append函数设计错误,realloc新地址未回传
    你定义的append函数声明返回int*类型,但内部没有返回值,且C语言为值传递,函数内修改形参v不会更新外部实参的direction指针。当realloc申请新内存块并释放旧块后,外部的direction仍指向已被释放的旧内存,成为野指针,后续访问、扩容或最终执行free时就会触发内存损坏错误。
  2. 内存分配单位错误
    所有动态内存分配代码中,你均使用sizeof(int*)(指针类型大小)作为分配单位,但你存储的是int类型的方向值,应改为sizeof(int)。该问题会引发隐式内存越界,是内存 corruption 的常见诱因。
  3. 多线程共享变量未同步
    子线程会直接修改*direction的值,主线程会调用realloc修改direction本身的指向,两个线程未加互斥锁同步,会导致子线程可能访问已释放的旧地址,引发非法内存访问。

具体修复代码

1. 修复append函数

int *append(int *v, int size, int value) // append data to vector
{
    size = size + 1;
    puts("Reallocing memory ...");
    printf("\nCurrent size: %d\n", size);
    // 修改分配单位为sizeof(int),新增空指针判断
    int *new_v = (int*)realloc(v, size * sizeof(int));
    if (new_v == NULL) {
        perror("realloc failed");
        exit(EXIT_FAILURE);
    }
    puts("Memory reallocating sucessful!");
    new_v[size-1] = value;
    return new_v; // 返回新指针
}

2. 调整append调用逻辑

由于需要修改外部的direction指针,你需要将updateGame函数的direction参数改为二级指针,或者将append的返回值回传给原指针:

// updateGame函数参数改为二级指针
void updateGame(char game[SIZE_X][SIZE_Y], position *player_position, int **direction, int it, int *length)
{
    // 原有逻辑不变,仅修改append调用行
    if (game[i][j] == '+') {
        *length = *length+1;
        *direction = append(*direction, *length, (*direction)[it]);
    }
    // 其余访问direction的地方也要对应调整为(*direction)[xxx]
}

3. 修复初始内存分配

将main函数中初始分配direction的代码修改为:

int *direction = (int*)malloc(1*sizeof(int)); // 分配单位改为int大小

4. 新增互斥锁同步线程

// 全局新增互斥锁定义
pthread_mutex_t dir_mutex = PTHREAD_MUTEX_INITIALIZER;

// 子线程修改direction时加锁
void *readMove(void *data)
{
    int *direction = ((int*) data);
    pthread_detach(pthread_self());
    while (collision) {
        if (getch() == '\033') {
            // 原有按键处理逻辑不变,仅修改赋值部分
            pthread_mutex_lock(&dir_mutex);
            switch(getch()) {
                case 'A':
                    *direction = 0;
                    break;
                case 'B':
                    *direction = 2;
                    break;
                case 'C':
                    *direction = 1;
                    break;
                case 'D':
                    *direction = 3;
                    break;
            }
            pthread_mutex_unlock(&dir_mutex);
            // 其余清屏逻辑不变
        }
    }
    pthread_exit(NULL);
}

// 主线程访问direction时也要加锁

其他需修复的逻辑错误

  • main函数中循环变量i从未自增,调用updateGame时传入的it永远为0,导致蛇的身体永远不会按照历史方向移动,需要在每次调用updateGame后执行i++,同时注意数组访问越界判断。
  • 子线程当前修改的是direction[0],但你的direction数组存储的是每一步的历史方向,需要调整为修改最新的方向值,否则按键操作不会生效。

内容的提问来源于stack exchange,提问作者Leonardo Araujo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 14:24:03