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函数。 由于maingrid未初始化,因此会出现未定义的行为。

这是我的修复方法的一个例子:

 #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; }