访问主(在函数中分配)中动态分配的内存时出现 Seg 错误,C



所以我要做的是使用指针创建一个二维数组作为矩阵。我在 CreateMatrix 函数中放置了一个双指针以及行/列,然后将数组动态分配到其中。我把 10 个填进去测试,这表明它们都已分配。但是,当我尝试访问 2D 数组的任意值时,我会出现段错误。不管它是否发生在函数中,动态分配不应该存储在堆上,因此它应该工作吗?

void CreateMatrix(int ** matrix, int row, int col){
int i, j;
matrix = (int**)malloc(row* sizeof(int*));
for (i = 0; i < row; i++) {
matrix[i] = (int*)malloc(col* sizeof(int));
for (j = 0 ; j < col; j++) {
matrix[i][j] = 10;
printf("i: %d, j: %dn", i,j);
printf("%d",matrix[i][j]);
}
}
}

主要:

int ** matrix1;
int m1row, m1col = 5;
CreateMatrix(matrix1, m1row, m1col);
fprintf(stdout,"Testing if got out");
fflush(stdout);
printf("This should be 10 : %d",matrix1[0][0]); //definitely segfaults here

另外,一个附带问题;有人告诉我,在 C 中传递"通过引用"时,不仅需要在函数定义中提供指针,还需要在函数调用的变量上有一个与号。就像我想通过引用传递矩阵 a 一样:CreateMatrix(&a, b, c);而不是CreateMatrix(a, b, c);.如果我使用 &,当我需要双指针时,我会收到一个不兼容错误,说参数是三指针。(这在理论上是有道理的,因为你正在传递双指针的位置(。那么 & 仅用于非指针变量吗?

CreateMatrix中的matrix是指针matrix1的副本。当您在该函数中分配给matrix时,main中的matrix1不受影响。

int** CreateMatrix(int row, int col){
int i, j;
int **matrix = (int**)malloc(row* sizeof(int*));
for (i = 0; i < row; i++) {
matrix[i] = (int*)malloc(col* sizeof(int));
for (j = 0 ; j < col; j++) {
matrix[i][j] = 10;
printf("i: %d, j: %dn", i,j);
printf("%d",matrix[i][j]);
}
}
return matrix;
}
int main() {
// ...
int **matrix1 = CreateMatrix(row, col);
// ...
return 0;
}

如果要保留void返回类型,则获取指向int**指针的指针,并在main中传递该指针的地址。

void CreateMatrix(int ***matrix, int row, int col){
int i, j;
*matrix = (int**)malloc(row* sizeof(int*));
for (i = 0; i < row; i++) {
(*matrix)[i] = (int*)malloc(col* sizeof(int));
for (j = 0 ; j < col; j++) {
(*matrix)[i][j] = 10;
printf("i: %d, j: %dn", i,j);
printf("%d", (*matrix)[i][j]);
}
}
}

int main() {
int **matrix1;
CreateMatrix(&matrix1, 10, 10);
printf("This should be 10 : %d",matrix1[0][0]);
return 0;
}

变量驻留在内存中。指针存储具有特定类型的变量的内存地址。与号&给出变量的内存地址。

在这里,&将地址返回到int**指针matrix1,然后将其传递给CreateMatrix。请注意,CreateMatrix的参数matrix已更改为指向int**指针的指针。

取消引用指针会得到指针指向的对象。在这里,当我们分配给*matrix时,我们所做的本质上是使用matrix1的内存地址(通过matrix传递(来获取CreateMatrix中的matrix1,并将 malloc 分配的内存块的开头分配给matrix1

在原始代码中,CreateMatrix中的matrix是指针matrix1值的副本(可能是垃圾,因为它未初始化(。

当你赋值给matrix时,你不是在修改matrix1,你只是在修改一个局部变量。

您提到的代码几乎没有问题。 首先m1row值没有定义,所以它可能会考虑一些垃圾值,所以分配值像

int m1row = 5, m1col = 5;

其次,您将matrix1传递给CreateMatrix()函数并在CreateMatrix()函数中创建动态数组,但没有将动态分配的地址返回给main()函数,这会导致访问时分段错误

printf("This should be 10 : %d",matrix1[0][0]);

同样不需要强制转换malloc()结果,如此处所述。

示例代码

int** CreateMatrix(int row, int col){
int i, j;
int **matrix = malloc(row* sizeof(*matrix)); /* no need to cast the malloc result */
for (i = 0; i < row; i++) {
matrix[i] = malloc(col* sizeof(**matrix));
for (j = 0 ; j < col; j++) {
matrix[i][j] = 10;
#if 0
printf("i: %d, j: %dn", i,j);
printf("%d n",matrix[i][j]);
#endif
}
}
return matrix; /* return the dynamic array */
}
int main(void){
int m1row = 5, m1col = 5;
int **matrix1 = CreateMatrix(m1row, m1col);
printf("nThis should be 10 : %dn",matrix1[0][0]); 
return 0;
}

CreateMatrix函数的matrix参数分配给该函数的堆栈上,这意味着它是它的本地。使用 malloc 分配内存时,局部变量matrix指向该内存。main 中的matrix变量不会因此而更新,这是因为参数默认按值传递。

为了使它工作,你必须将matrix变量的地址(使用&运算符(从main传递到CreateMatrix,即它的签名应该有int *** matrix。在函数内部,您必须使用*运算符更新它。这样:

*matrix = (int **) malloc (row * sizeof(int *))

另一种选择是从CreateMatrix函数返回分配的内存。

最新更新