这是我的代码,它为参数指定的大小矩阵分配空间,并返回指向所述矩阵的指针:
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()
函数返回时,分配的内存被释放(因为我遇到了分段错误)。但为什么?我所做的只是为给定的指针分配内存,而这一切都是在子函数中完成的。
总结我的问题:为什么我在第二段代码中出现分段错误? 非常感谢你!
答案 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 **中,通过值(指针)传递,因此函数中的更改不会影响调用者的函数。您必须通过引用传递此值。