动态分配矩阵的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
[]