0

这是我的代码,它为参数指定大小的矩阵分配空间,并返回指向所述矩阵的指针:

int **allocateSpace(int row, int col){  
   int i;
   int **a;
   a = malloc(sizeof(int *) * row);
   for(i = 0; i < row; i ++)                                               
      a[i] = malloc(sizeof(int) * col);  
   return a;
}      

上面的代码按预期工作。

但是,当我将代码更改为以下形式时,会出现分段错误:

void allocateSpace(int **a, int row, int col){
    int i;
    a = malloc(sizeof(int *) * row);
    for(i = 0; i < row; i ++)
      a[i] = malloc(sizeof(int) * col);
}

似乎从allocateSpace()函数返回时,分配的内存被释放(因为我遇到了分段错误)。但为什么?我所做的只是为给定的指针分配内存,这一切都在子函数中完成。

总结我的问题:为什么我在第二段代码中出现分段错误?非常感谢你!

4

4 回答 4

6

因为您需要传入指向指针的指针才能分配分配的内存:

void allocateSpace(int ***a, int row, int col){
    int i;
    *a = malloc(sizeof(int *) * row);
    for(i = 0; i < row; i ++)
      ( *a )[i] = malloc(sizeof(int) * col);
}

要调用它,您需要传递 a 的地址int**

int** ppData;

allocateSpace( &ppData, 10, 10 );
于 2012-04-04T10:29:39.370 回答
0

问题是您正在尝试更改按值传递的指针:

void allocateSpace(int **a, int row, int col){
  // ...
}

int** a这里是按传递的(即指针值被复制到堆栈中以便将其用作函数参数)。

当你这样做时

a = malloc(sizeof(int *) * row);

您只更改指针的副本,一旦函数返回,您的更改将被丢弃。

解决方法是通过引用传递指针,即

void allocateSpace(int ***a, int row, int col){
//...
}

并按照参考更改实际值:

*a = malloc(sizeof(int *) * row);
于 2012-04-04T10:32:14.710 回答
0

在第二种情况下,您正在修改函数的参数a——即按值传递的本地副本。所以,如果你调用这样的函数:allocateSpace(myptr,N,M)myptr将不会被修改 - 函数的本地副本将。因此,myptr包含它在调用之前包含的任何内容 - 可能是垃圾。您需要将函数参数更改为:(哦,太恐怖了),然后在函数体中的每个引用之前int ***a添加一个额外的(取消引用操作)。*a

将此与您想要修改函数中的简单 int 的情况进行比较 - 参数应该是int *并且函数体中的分配应该去*a。这里同样适用 - 需要额外的取消引用级别才能实现您的目标。

于 2012-04-04T10:33:04.860 回答
0

在第二个函数中,int **a 通过值(指针)传递,因此函数中的更改不会影响调用者的函数。您必须通过引用传递此值。

于 2012-04-04T10:33:26.563 回答