free() 后的分段错误

Segmentation fault after a free()

我正在尝试动态分配一个矩阵 N*N 并在其中放入随机数(介于 0 和 h-1 之间)。我还必须创建一个取消分配它的函数。问题是我必须使用结构,而且我不太习惯它们。结构“game_t”在另一个文件中定义并包含在内。

game_t * newgame( int n, int m, int t){
    game_t x, *p;
    int i,j;
    p=&x;
    x.t=t;
    x.n=n;    /* structure game has n,t,h,board as keys*/
    x.h=h;
    srand(time(NULL)); 
    x.board=malloc(n*sizeof(int*));    /*Allocate*/
    if (x.board==NULL) return NULL;
    for (i=0;i<n;i++){
              x.board[i]=malloc(n*sizeof(int));}
    for (i=0;i<n;i++){   /*put random numbers*/
             for (j=0;i<n;j++){
                     x.board[i][j]=rand()%h;}}
    return p;
}

void destroy(game_t *p){
    int i;
    for (i=0;i<p->n;i++){
        free(p->board[i]);}
    free(p->board);
}

p 是指向 局部变量 x 的指针。一旦离开函数 newgame,该变量将不复存在,并且 p 现在是一个悬挂指针。您无权访问它。

解决方案很简单:return 来自 newgamegame_t,而不是 newgame_t *,并且不要使用 p

game_t newgame(int n, int m, int t) {
    game_t x;
    int i, j;
    x.t = t;
    x.n = n;    /* structure game has n,t,h,board as keys*/
    x.h = h;
    srand(time(NULL)); 
    x.board = malloc(n * sizeof (int*));    /*Allocate*/
    if (x.board == NULL) {
        perror("newgame");
        exit(1);
    }
    for (i = 0; i < n; i++) {
        x.board[i] = malloc(n * sizeof(int));
        if (x.board[i] == NULL) {
            perror("newgame");
            exit(1);
        }
    }
    for (i = 0; i < n; i++) {   /*put random numbers*/
        for (j = 0; i < n; j++) {
            x.board[i][j] = rand() % h;
        }
    }
    return x;
}

请注意,这意味着如果分配失败,您将无法再return NULL。我已经修改了代码以退出,但可能需要一种不同的策略(尽管可能不是:分配失败通常很难处理,并且退出 - 带有错误消息! - 是一个 OK 响应)。

你return指向局部变量x的指针。一旦离开它们的范围,局部变量就会消失。

game_t * newgame( int n, int m, int t){
    game_t x, *p;
    int i,j;
    p=&x;    // <<<< p points to the local variable x
    x.t=t;
    x.n=n;
    x.h=h;
    srand(time(NULL)); 
    x.board=malloc(n*sizeof(int*));
    if (x.board==NULL) return NULL;
    for (i=0;i<n;i++){
              x.board[i]=malloc(n*sizeof(int));}
    for (i=0;i<n;i++){
             for (j=0;i<n;j++){
                     x.board[i][j]=rand()%h;}}
    return p;
}

你可能想要这个:

game_t * newgame( int n, int m, int t){
    game_t *p = malloc(sizeof (*p));   // allocate memory for a new game_t
    int i,j;
    p->t=t;
    p->n=n;
    p->h=h;
    srand(time(NULL)); 
    p->board=malloc(n*sizeof(int*));
    if (p->board==NULL) return NULL;
    for (i=0;i<n;i++){
              p->board[i]=malloc(n*sizeof(int));}
    for (i=0;i<n;i++){
             for (j=0;i<n;j++){
                     p->board[i][j]=rand()%h;}}
    return p;
}

顺便说一句:你应该使用有意义的变量名。例如p应该命名为new等等

奖励: 在程序开始时仅 调用 一次 。