调用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
相关产品推荐
相关产品推荐

