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 来自 newgame
的 game_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
等等
奖励: 在程序开始时仅 调用 一次 。
我正在尝试动态分配一个矩阵 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 来自 newgame
的 game_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
等等
奖励: 在程序开始时仅 调用 一次 。