在c中的子函数中分配内存时出现奇怪的分段错误

时间:2012-04-04 10:26:58

标签: c segmentation-fault

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

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 个答案:

答案 0 :(得分: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);
}

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

int** ppData;

allocateSpace( &ppData, 10, 10 );

答案 1 :(得分: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);

答案 2 :(得分:0)

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

将此与您想要修改函数中的简单int的情况相比较 - param应为int *,函数体中的赋值应转到*a。同样适用于此 - 需要一个额外的解除引用级别来实现您的目标。

答案 3 :(得分:0)

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