在main(在函数中分配)访问动态分配的内存时出现段错误,C [重复]

问题描述 投票:0回答:3

这个问题在这里已有答案:

所以我要做的是使用指针创建一个二维数组作为矩阵。我将一个双指针放入我的CreateMatrix函数,以及行/列,我动态地将数组分配到它们中。我在其中填写了10个进行测试,结果显示它们已全部分配。但是在main中,当我尝试访问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: %d\n", 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中传递'by reference'时,不仅需要函数定义中的指针,还需要函数调用的变量上的&符号。如果我想通过引用传递矩阵a:CreateMatrix(&a, b, c);而不是CreateMatrix(a, b, c);。如果我使用&,我得到一个不兼容错误,说我的参数是一个三指针,当我需要一个双指针。 (理论上这是有意义的,因为你传递了双指针的位置)。然后是&仅用于非指针变量?

c multidimensional-array heap-memory
3个回答
1
投票

matrixCreateMatrix是指针matrix1的副本。当您在该函数中指定matrix时,matrix1中的main不受影响。

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: %d\n", 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: %d\n", 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。请注意,matrix的参数CreateMatrix已更改为指向int**指针的指针。

取消引用指针可以获得指针指向的对象。在这里,当我们分配给*matrix时,我们正在做的主要是使用matrix1的内存地址(通过matrix传递)来获取matrix1中的CreateMatrix,并将malloc分配的内存块的开始分配给matrix1

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

当你分配给matrix时,你没有修改matrix1,你只是在修改一个局部变量。


1
投票

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

int m1row = 5, m1col = 5;

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

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

同样铸造malloc()结果不需要像尖头here

示例代码

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: %d\n", 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 : %d\n",matrix1[0][0]); 
    return 0;
}

0
投票

matrix函数的CreateMatrix参数在该函数的堆栈上分配,这意味着它是本地的。当您使用malloc分配内存时,局部变量matrix指向该内存。 main中的matrix变量没有得到更新,这是因为默认情况下参数是按值传递的。

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.