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

调用free()后出现Segmentation fault 基于结构体的N*N矩阵动态分配问题

问题梳理

你的代码存在以下几个核心错误:

  • 返回栈内存地址:局部变量game_t x存储在函数栈空间,函数执行结束后栈空间会被系统回收,返回的指针属于野指针,后续访问会触发未定义行为,必须在堆上申请game_t结构体的内存空间。
  • 循环逻辑错误:填充随机数的内层循环判断条件误写为i<n,会导致无限循环或内存越界。
  • 未定义参数h:函数参数列表中没有传入h参数,直接赋值x.h=h无法通过编译,需要补充该参数,同时你定义的参数m全程未使用,可以直接删除。
  • 随机种子初始化位置不合理:srand(time(NULL))仅需要在程序全局执行一次即可,多次调用newgame时重复初始化会导致随机数序列重复,建议移到主函数启动阶段执行。
  • 内存释放逻辑缺失:destroy函数只释放了二维矩阵的内存,没有释放game_t结构体本身的堆内存,会造成内存泄漏。
修正后代码
#include <stdlib.h>
#include <time.h>
// 此处默认你已经正确引入了game_t的定义
game_t * newgame(int n, int t, int h){
    // 堆上分配game_t结构体空间
    game_t *p = malloc(sizeof(game_t));
    if (p == NULL) {
        return NULL;
    }
    int i,j;
    p->t = t;
    p->n = n;
    p->h = h;
    // 分配二维矩阵第一维
    p->board = malloc(n * sizeof(int*));
    if (p->board == NULL) {
        // 分配失败要释放已经申请的p,避免内存泄漏
        free(p);
        return NULL;
    }
    // 分配二维矩阵第二维
    for (i = 0; i < n; i++) {
        p->board[i] = malloc(n * sizeof(int));
        if (p->board[i] == NULL) {
            // 某一行分配失败,要释放之前已经申请的所有内存
            for (int k = 0; k < i; k++) {
                free(p->board[k]);
            }
            free(p->board);
            free(p);
            return NULL;
        }
    }
    // 填充随机数,范围0~h-1
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            p->board[i][j] = rand() % h;
        }
    }
    return p;
}

void destroy(game_t *p){
    if (p == NULL) {
        return;
    }
    for (int i = 0; i < p->n; i++) {
        free(p->board[i]);
    }
    free(p->board);
    // 释放结构体本身的内存
    free(p);
}

// 提示:srand(time(NULL)) 请放在main函数中,程序启动后执行一次即可,不要放在newgame里

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 23:00:00