我想创建一个函数来分配(malloc
/ calloc
)一个声明为双指针的矩阵。我理解双指针矩阵如何工作以及如何用malloc
分配它,但是当我传递我的矩阵(在main()
中声明并初始化为NULL
)时,我的程序崩溃了。我认为错误在于我的allocMatrix()
函数,因为如果我在main
中分配矩阵,则一切顺利。谢谢: - )
主:
#include <stdio.h>
#include <stdlib.h>
#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;
}
答案 0 :(得分:11)
永远不要使用指针指针来分配多维数组。它是广泛传播但是错误和不正确的做法。这样做不会给你一个真正的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的二维二维数组的大小。它使用了C99标准中的可变长度数组的概念,它允许在运行时指定数组维度。
数组指针在C中是一种有点特殊的类型,它能够指向整个数组,而不仅仅是数组的第一项,正如普通指针所做的那样。与常规指针不同,数组指针知道数组的大小。
数组指针写为type(*name)[size]
,因此例如,指向5个整数的数组的数组指针将写为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]
将给出数组数组中的第一个数组。在表达式中使用时,任何数组名称的通常规则是&#34;衰变&#34;到指向第一个元素的指针。这同样适用,因此(*arr_ptr)[0]
也将与指向第一个数组中第一个元素的指针相同。 (*arr_ptr)[0][0]
将给出第一个数组的第一个元素。
现在这种语法(*arr_ptr)[0][0]
看起来有点难以阅读;为了得到2D数组的第一项,我们只用arr[0][0]
编写。因此,在声明数组指针时,有一个方便的技巧。而不是声明完整和正确的数组指针:int(*matrix)[x][y]
,一个指向维数x * y的二维数组的数组指针,我们将其声明为int(*matrix)[y]
,这是一个指向一维数组的数组指针维度。它将指向2D数组中的第一个项目,即一个大小为y的一维数组。我们知道2D数组包含x个这样的项目。
由于这个技巧,我们现在能够使用与访问2D数组时相同语法的数组指针,即matrix[i][j]
,而不是难以阅读{{ 1}}。
答案 1 :(得分:1)
在哪里写if let headerView = view as? UITableViewHeaderFooterView {
headerView.textLabel?.text? = headerView.textLabel?.text?.capitalized ?? ""
}
你可以改变你的矩阵类型
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;
}
可以避免内存泄漏,但正如Lundin所说,最好不要使用2d数组
永远不要使用指针指针来分配多维数组。它是广泛传播但是错误和不正确的做法。这样做不会给你一个真正的2D数组,并且由于堆碎片会导致代码变慢。它还使代码更难以编写,读取和维护,从而增加了内存泄漏的可能性。 相反,在相邻的存储单元中正确分配2D数组
[]
答案 2 :(得分:0)
这里的问题是,您是否正在将mat
本身传递给分配器函数,该函数在C
使用时返回时无法从函数中保持分配的内存函数参数传递的值传递。
您需要将指针传递给mat
并进行相应的分配。
答案 3 :(得分:0)
您应该通过引用将矩阵传递给allocMatrix
。
将您的功能定义为int allocMatrix(int ***matrix, int nRow, int nCol)
并将matrix
替换为*matrix
(请注意索引的语法,它必须是(*matrix)[i]
,而不是*matrix[i]
)
这意味着您将此功能称为allocMatrix(&mat, nRow, nCol)
。