C.分段功能修改动态分配的2d数组时的错误

时间:2009-12-16 22:04:59

标签: c arrays memory pointers

我需要的是一个修改给定指针的函数,如下所示:

void intMatrixAll(int row, int col, int **matrix);

现在,函数应该分配内存并且可以使用矩阵。行和列在运行时给出。

#include <stdio.h>
#include <stdlib.h>
#define PRINTINT(X) printf("%d\n", X);
void intMatrixAll(int row, int col, int **matrix);

int main(void) {
   int testArrRow = 4;
   int testArrCol = 6;
   int **testMatrix = NULL;
   intMatrixAll(testArrRow, testArrCol, testMatrix);
   testMatrix[2][2] = 112; //sementation fault here :(
   PRINTINT(testMatrix[2][2]);
   system("PAUSE");
   return 0;
}

void intMatrixAll(int row, int col, int **matrix) {
   printf("intMatrixAll\n");
   //allocate pointers:
   matrix = malloc(row * sizeof(int *));
   if(matrix == NULL) printf("Failed to allocate memmory.\n");
   for(int i=0; i<row; i++) {
      //allocate space for cols: 
      matrix[i] = malloc(col * sizeof(int));
      if(matrix[i] == NULL) {
         printf("Failed to allocate memmory for arr[%d].\n", i);
         exit(0);
      }
   }
}

为什么我会收到错误?

3 个答案:

答案 0 :(得分:6)

测试矩阵仍为NULL。您需要从intMatrixAll()返回新分配的指针。从函数返回值,或者传入testMatrix的地址,以便设置它。

#include <stdio.h>
#include <stdlib.h>
#define PRINTINT(X) printf("%d\n", X);
void intMatrixAll(int row, int col, int **matrix);

int main(void) {
   int testArrRow = 4;
   int testArrCol = 6;
   int **testMatrix = NULL;
   intMatrixAll(testArrRow, testArrCol, &testMatrix);
   testMatrix[2][2] = 112; //sementation fault here :(
   PRINTINT(testMatrix[2][2]);
   system("PAUSE");
   return 0;
}

void intMatrixAll(int row, int col, int ***matrix) {
   printf("intMatrixAll\n");
   //allocate pointers:
   *matrix = malloc(row * sizeof(int *));
   if(*matrix == NULL) printf("Failed to allocate memmory.\n");
   for(int i=0; i<row; i++) {
      //allocate space for cols: 
      *matrix[i] = malloc(col * sizeof(int));
      if(*matrix[i] == NULL) {
         printf("Failed to allocate memmory for arr[%d].\n", i);
         exit(0);
      }
   }
}

答案 1 :(得分:2)

因为修改intMatrixAll()内的矩阵不会修改main()中的testMatrix。如果你想能够修改main的变量,你需要传递一个指向它的指针。所以你需要将intMatrixAll更改为:

void intMatrixAll(int row, int col, int ***matrix)

在intMatrixAll中,您现在需要将matrix更改为*matrix(并且当您为其编制索引时,您需要(*matrix)[...]

最后,您需要将对intMatrixAll的调用更改为:

intMatrixAll(testArrRow, testArrCol, &testMatrix);

原因是C只支持pass-by-value和pass-by-value不支持被调用函数改变调用者中变量的值。

为了修改调用者中变量的值,你需要传递一个指向变量的指针,然后让被调用的函数取消引用它。

答案 2 :(得分:0)

有关类似内容的讨论,请参阅here。它出错的原因是因为你没有将int的指针指针从函数intMatrixAll传递回主程序。换句话说,您将传递一个双指针参数指向int的按值,而不是通过引用,并尝试在事实上访问testMatrix仍然是NULL

因此,您需要添加另一级别的间接,即*,并使用该间接作为将双指针更改为malloc d的方法,并使主例程看到{{1}确实被分配了。

见上文R. Samuel Klatchko的答案。

作为一般规则,如果要通过引用将指针作为参数传递给某个东西,请添加另一个间接级别。在您的情况下,您将一个双指针传递给int,将该参数作为函数中的三指针。

int **testMatrix;
void intMatrixAll(int row, int col, int ***matrix){
  // In here use this (*matrix)
}

// Then the calling of the function would look like this
intMatrixAll(testArrRow, testArrCol, &testMatrix); 

// Note the ampersand above to treat this double pointer passed in by reference

希望这有助于理解, 最好的祝福, 汤姆。