动态分配矩阵的function

我想创建一个函数来分配(使用malloc / calloc )一个声明为双指针的矩阵。 我理解双指针矩阵如何工作以及如何使用malloc分配它,但是当我传递我的矩阵(在main()声明并初始化为NULL )时,我的程序崩溃了。 我想错误是我的allocMatrix()函数,因为如果我在main分配矩阵,所有工作都顺利进行。 谢谢 :-)

主要:

 #include  #include  #include "Data.h" #define ROW 5 #define COL 5 int main(void) { int i,j, ret; int nRow, nCol; int **mat=NULL; // double pointer matrix nRow = 0; nCol = 0; //Insert n of row and columns printf("Insert n of rows and columns:\n"); scanf("%d %d", &nRow, &nCol); //Functions to allocate matrix ret=allocMatrix(mat, nRow, nCol); printf("Return value: %d\n",ret); /* this code works perfect! mat= malloc(nRow * sizeof(int)); i=0; while( i < nRow) { mat[i]=malloc(nCol * sizeof(int)); i++; } */ //Get Values from stdin i=0; while( i < nRow) { j=0; while (j < nCol) { printf("Insert value pos[%d,%d]:\n", i, j); scanf("%d", &mat[i][j]); j++; } i++; } //Print values i=0; while (i < nRow) { j=0; while( j < nCol) { printf("Value pos[%d,%d] is: %d \n", i, j, mat[i][j]); j++; } i++; } system("pause"); return EXIT_SUCCESS; } 

allocateMatrix函数:

 int allocMatrix(int **matrix, int nRow, int nCol) { int i; int ext_status; //Classic allocation method for matrix matrix= malloc( nRow * sizeof(int)); if ( matrix != NULL) { i=0; while (i < nRow) { matrix[i]= malloc(nCol * sizeof(int)); if( matrix[i] != NULL) ext_status= 1; else ext_status= 0; i++; } } else ext_status= 0; return ext_status; } 

切勿使用指针指针来分配多维数组。 它是广泛传播但不好和不正确的做法。 这样做不会给你一个真正的2D数组,并且由于堆碎片会导致代码变慢。 它还使代码更难以编写,读取和维护,从而增加了内存泄漏的可能性。

相反,在相邻的存储单元中正确分配2D数组,如下所示:

 int x; int y; // store some values in x and y here int(*matrix)[y] = malloc (sizeof(int[x][y])); if(matrix == NULL) { // error handling here } matrix[i][j] = something; // do something with the matrix free(matrix); 

如果您坚持将此代码保留在函数中,那么它将是:

 void* allocMatrix (int nRow, int nCol) { return malloc (sizeof(int[nRow][nCol])); } int(*matrix)[y] = allocMatrix(x, y); 

编辑:代码和数组指针的解释。

在行int(*matrix)[y] = malloc (sizeof(int[x][y]));sizeof(int[x][y])非常直接,它只是尺寸为x * y的二维int数组的大小。 它使用了C99标准中的可变长度数组的概念,它允许在运行时指定数组维度。

数组指针在C中是一种有点特殊的类型,它能够指向整个数组,而不是仅仅指向数组的第一项,就像普通指针一样。 与常规指针不同,数组指针知道数组的大小。

数组指针被写为type(*name)[size] ,因此例如,一个指向5个int数组的数组指针将被写为int(*arr_ptr)[5] = &the_array;

当访问指向的内容时,数组指针的行为与任何指针一样,您可以使用*访问它的内容。 所以*arr_ptr给出了指向的数组,而(*arr_ptr)[0]给出了该数组的第一项。

对于多维数组,适用相同的规则。 给定数组int arr[x][y] ,指向此类型的数组指针将为int(*arr_ptr)[x][y] = &arr; 。 访问内容*arr_ptr将为您提供一个二维数组,相当于一个数组数组。 (*arr_ptr)[0]因此将给出数组数组中的第一个数组。 在表达式中使用时,任何数组名称的通常规则是它“衰减”为指向第一个元素的指针。 这同样适用,因此(*arr_ptr)[0]也将与指向第一个数组中第一个元素的指针相同。 并且(*arr_ptr)[0][0]将给出第一个数组的第一个元素。

现在这个语法(*arr_ptr)[0][0]看起来有点难以阅读; 为了获得2D数组的第一项,我们在写作arr[0][0] 。 因此,在声明数组指针时,有一个方便的技巧。 而不是声明完整和正确的数组指针: int(*matrix)[x][y] ,一个指向维度为x * y的二维数组的数组指针,我们将其声明为int(*matrix)[y] ,是指向维度为y的1D数组的数组指针。 它将指向2D数组中的第一个项目,即一个大小为y的一维数组。 我们知道2D数组包含x个这样的项目。

由于这个技巧,我们现在能够使用与访问2D数组时相同语法的数组指针,即matrix[i][j] ,而不是难以阅读(*matrix)[i][j]

这里的问题是,你将mat本身传递给allocator函数,该函数在返回时无法保存函数中分配的内存,因为C使用pass-by-value进行函数参数传递。

您需要将指针传递给mat并相应地进行分配。

你应该通过引用将矩阵传递给allocMatrix的值。

将你的函数定义为int allocMatrix(int ***matrix, int nRow, int nCol)并用*matrix替换matrix (顺便指一下索引的语法,它必须是(*matrix)[i] ,而不是*matrix[i] )。

这意味着您将此函数称为allocMatrix(&mat, nRow, nCol)

在哪里写double你可以改变你的矩阵类型

 void allocMatrix(double ***matrix, int row, int col){ int i = 0; *matrix = (double **)malloc(sizeof(double *) * row); for(i = 0; i < col; i++){ *(*matrix + i) = (double *)malloc(sizeof(double) * col); } } void deallocMatrix(double **matrix, int row){ int i = 0; for(i = 0; i < row; i++){ free(matrix[i]); } free(matrix); } 

在主要时你可以像这样使用它们

 int main(){ int i = 0, j = 0, k = 0, row = 3, col = 4; double **myMatrix = NULL; allocMatrix(&myMatrix, row, col); for(i = 0; i < row; i++){ for(j = 0; j < col; j++){ myMatrix[i][j] = k++; printf("%.0lf\t", myMatrix[i][j]); } printf("\n"); } deallocMatrix(myMatrix, row); return 0; } 

产量

 1 2 3 4 5 6 7 8 9 10 11 12 

这可能会避免内存泄漏,但正如Lundin所说,最好不要使用2d数组

切勿使用指针指针来分配多维数组。 它是广泛传播但不好和不正确的做法。 这样做不会给你一个真正的2D数组,并且由于堆碎片会导致代码变慢。 它还使代码更难以编写,读取和维护,从而增加了内存泄漏的可能性。 而是在相邻的存储器单元中正确分配2Darrays

[]