根据C FAQ on instantiating a matrix using a double pointer的建议,我偶然发现了另一个问题。我设法解决了这个问题,但很难理解为什么它以某种方式工作而不是另一种方式。
我有以下代码可以使用,然后我会告诉你一点不起作用,我希望你能解释原因:
#include <stdio.h>
#include <stdlib.h>
int HEIGHT = 20;
int WIDTH = 20;
int ** curr_grid;
/**
* Generate an array with the given height and length
*/
int ** create_grid() {
int ** grid;
grid = malloc(sizeof(int *) * HEIGHT);
int row;
for (row = 0; row < HEIGHT; row++)
grid[row] = malloc(sizeof(int) * WIDTH);
return grid;
}
/* Entry Point main */
int main(int argc, char** argv) {
curr_grid = create_grid();
curr_grid[0][0] = 0;
free(curr_grid); // Release heap resources
return 0;
}
为网格分配内存并以这种方式返回指针。但是,我首先尝试了另一种方式,我确信它也应该有效,但事实并非如此:
#include <stdio.h>
#include <stdlib.h>
int HEIGHT = 20;
int WIDTH = 20;
int ** curr_grid;
/**
* Generate an array with the given height and length
*/
create_grid(int ** grid) {
grid = malloc(sizeof(int *) * HEIGHT);
int row;
for (row = 0; row < HEIGHT; row++)
grid[row] = malloc(sizeof(int) * WIDTH);
}
/* Entry Point main */
int main(int argc, char** argv) {
create_grid(curr_grid);
curr_grid[0][0] = 0; // Segmentation Fault
free(curr_grid); // Release heap resources
return 0;
}
这样做会在指示的行上终止分段错误。但是,我的印象是通过引用传递变量允许您修改它。
为什么这不起作用?
答案 0 :(得分:2)
你没有通过说create_grid(curr_grid);
来传递指针的地址
这里它传递curr_grid指针中存在的值(随机值)并将该值带入网格中。一旦函数执行完毕,就会从堆栈中获取它。
尝试传递指针的地址,然后工作正常。
create_grid(&curr_grid);
编辑:检查以下链接,希望它可以帮助您进行图形表示
答案 1 :(得分:1)
你想要这个:
void create_grid(int ***grid) {
*grid = malloc(sizeof(int *) * HEIGHT);
int row;
for (row = 0; row < HEIGHT; row++)
(*grid)[row] = malloc(sizeof(int) * WIDTH);
}
/* Entry Point main */
int main(int argc, char** argv) {
create_grid(&curr_grid);
curr_grid[0][0] = 0;
free(curr_grid); // Release heap resources
return 0;
}
这就像下面的例子:
int MyFunction()
{
return 3 ; // we return directly 3
}
void main()
{
int a ;
a = MyFunction() ;
}
VS
void MyFunction1(int *pa)
{
*pa = 3 ; // we assign 3 to the memory location pointed by pa
}
void main2()
{
int a ;
MyFunction1(&a) ; // we pass the pointer to a /
// now a contains 3
}
答案 2 :(得分:0)
知道如何传递任何类型的变量(指针与否,规则保持不变)的方法是:
void create_grid(int **grid) {
grid = malloc(...);
...
}
在这里,您传递一个名为grid
的变量,并且您希望更改它的值grid = malloc(...);
,但由于您只使用grid
而没有任何*,因此您只有一个网格副本
对grids
值所做的任何更改都不会在函数外显示。
现在在这种情况下:
void create_grid(int ***grid) {
*grid = malloc(...);
...
}
现在,当您使用和'*'访问网格的值时,您知道,任何以这种方式完成的更改将在函数返回后保留,因为网格实际上是对二维数组的引用。
这很简单(无论变量是什么类型)。