繁体   English   中英

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

[英]Seg faulting when accessing dynamically allocated memory in main (allocated in function), C [duplicate]

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

所以我想做的是使用指针创建一个二维数组作为矩阵。 我将一个双指针以及行/列放入我的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: %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中通过“按引用”传递时,不仅在函数定义中需要指针,而且在函数调用的变量上使用与号。 类似于如果我想通过引用传递矩阵a: CreateMatrix(&a, b, c); 而不是CreateMatrix(a, b, c); 如果使用&,则当需要双指针时,会出现不兼容错误,提示参数为三指针。 (从理论上讲,这是有道理的,因为您要传递双指针的位置)。 然后&仅用于非指针变量吗?

CreateMatrix中的matrix是指针matrix1的副本。 当你分配到matrix在该函数, matrix1main是不受影响的。

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 注意, CreateMatrix的参数matrix已更改为指向int**指针的指针。

取消引用指针后,您将获得该指针指向的对象。 在这里,当我们分配给*matrix ,我们正在做的基本上使用的内存地址matrix1 (这是通过传递matrix ),以获得matrix1CreateMatrix ,并分配的内存的malloc分配到块的起始matrix1

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

当您分配给matrix ,您不是在修改matrix1 ,而只是在修改局部变量。

您提到的代码很少有问题。 首先, m1row值未定义,因此它可能会考虑一些垃圾值,因此将值分配为

int m1row = 5, m1col = 5;

其次,要传递matrix1CreateMatrix()函数和在创建动态阵列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: %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;
}

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM