malloc-ating函数中的多维数组
我正在尝试在C程序中分配2d数组。 它在这样的主函数中工作正常(如此处所解释):
#include #include int main(int argc, char ** argv) { int ** grid; int i, nrows=10, ncols=10; grid = malloc( sizeof(int *) * nrows); if (grid == NULL){ printf("ERROR: out of memory\n"); return 1; } for (i=0;i<nrows;i++){ grid[i] = malloc( sizeof(int) * ncols); if (grid[i] == NULL){ printf("ERROR: out of memory\n"); return 1; } } printf("Allocated!\n"); grid[5][6] = 15; printf("%d\n", grid[5][6]); return 0; }
但由于我必须使用不同的数组多次执行此操作,因此我尝试将代码移动到单独的函数中。
#include #include int malloc2d(int ** grid, int nrows, int ncols){ int i; grid = malloc( sizeof(int *) * nrows); if (grid == NULL){ printf("ERROR: out of memory\n"); return 1; } for (i=0;i<nrows;i++){ grid[i] = malloc( sizeof(int) * ncols); if (grid[i] == NULL){ printf("ERROR: out of memory\n"); return 1; } } printf("Allocated!\n"); return 0; } int main(int argc, char ** argv) { int ** grid; malloc2d(grid, 10, 10); grid[5][6] = 15; printf("%d\n", grid[5][6]); return 0; }
但是,虽然在分配时不会抱怨,但在访问arrays时会出现分段错误。 我阅读了关于衰变数组和类似主题的不同post,但我仍然无法弄清楚如何解决这个问题。 我想我没有正确地将2d数组传递给函数。
非常感谢。
那不是一个多维数组; 它是一个包含指向单维数组指针的单维数组。 多维数组不包含指针; 它们是单个内存块。
你的问题是你有一个指针指针,你试图通过参数从函数返回它。 如果你要这样做,你将需要一个指向指针的指针作为你的参数,你将不得不将指针的地址传递给指向该方法的指针。 如果不这样做,则不会更改main
变量grid
的值 – 您将作为参数复制的值更改为malloc2d
函数。 由于main
的grid
未初始化,因此会出现未定义的行为。
这是我的修复方法的一个例子:
#include #include int malloc2d(int *** grid, int nrows, int ncols){ int i; *grid = malloc( sizeof(int *) * nrows); if (*grid == NULL){ printf("ERROR: out of memory\n"); return 1; } for (i=0;i
补充说明:
- 如果单个分配失败,则会泄漏第一个数组的分配以及所有先前行的分配。 你需要在回来之前
free
打电话。 - 你正在通过参数返回,即使你真的不需要。 如果我写这个,我会让方法返回
int **
,并通过返回0
发出错误信号。
这是你的function,修复:
int malloc2d(int *** grid, int nrows, int ncols){ int i; *grid = (int**)malloc( sizeof(int *) * nrows); if (*grid == NULL){ printf("ERROR: out of memory\n"); return 1; } for (i=0;i
注意,该函数现在收到一个int***
,并将int**
的地址传递给函数。 然后该函数解引用int***
以将已分配的内存块的地址放入其中。
C是按值传递的。 总结你正在做的错误,这个例子应该是有帮助的 –
void foo( int *temp ) { temp = malloc(sizeof(int)) ; // temp is assigned to point to new location but the actual variable // passed from main do not point to the location temp is pointing to. *temp = 10 ; } int main() { int *ptr ; foo( ptr ) ; // ptr is still unintialized *ptr = 5 ; // Segmentation fault or Undefined behavior return 0; }
所以,你应该这样做 –
void foo( int **temp ) { *temp = malloc(sizeof (int) ); // ... }
现在将函数称为foo(&ptr);
在main()
函数中。
如果您仍希望malloc2d
返回状态代码,则参数必须是int***
类型:
int malloc2d(int *** grid, int nrows, int ncols){
你需要使用*grid
来引用提供的缓冲区:
int i; *grid = malloc( sizeof(int *) * nrows); if (*grid == NULL){ printf("ERROR: out of memory\n"); return 1; } for (i=0;i
然后,当调用malloc2d
,传递一个int**
的地址来填写:
int ** grid; malloc2d(&grid, 10, 10);
C实际上总是按值传递,所以当你传入’grid’时,你传入一个值,函数正在修改它自己的本地副本。 尝试传入’&grid’代替并适当修改malloc2d。
这不是你的分段故障问题,但你应该考虑使用单个malloc调用来分配网格所需的所有必要内存空间。
grid = malloc (nrows * ncols * sizeof(int *))
关于指针指针指针的Bill ONeary答案。
较短的应该在下面,每个网格元素的free(!)和初始化值:
#include #include #define NROWS 10 #define NCOLS 10 int main() { int (* grid)[NCOLS] = calloc(NROWS,sizeof*grid); /* no more needed here malloc2d(grid, 10, 10); */ grid[5][6] = 15; printf("%d\n", grid[5][6]); free(grid); /* every c/malloc need a free */ return 0; }