我试图用数组(malloc-ed)做一些事情,即自定义结构的arr
。通过引用函数传递数组。每当我在运行时尝试索引函数中arr[0]
以外的任何内容时,我会得到一个段错误(例如(*arr[1])->i = 3;
)。为什么会这样?
完整的源代码是:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 100
typedef struct{
int i;
float f;
}foo;
void doSomething(foo ***arr);
int main()
{
foo **arr = (foo**) malloc (SIZE * sizeof(foo*));
int i;
for(i = 0; i < SIZE; i++)
arr[i] = (foo*)malloc(sizeof(foo));
arr[1]->i = 1;
printf("Before %d\n",arr[1]->i );
doSomething(&arr);
printf("After %d\n",arr[1]->i );
return 0;
}
void doSomething(foo ***arr)
{
(*arr[1])->i = 3;
}
答案 0 :(得分:2)
你的问题就在这一行
(*arr[1])->i = 3;
由于下标运营商的评估precedes是解除引用的评估,因此它等同于以下内容:
(*(arr[1]))->i = 3;
这显然是错误的。你需要
(*arr)[1]->i = 3;
因此
注意:
malloc
#include <stdlib.h>
以解决警告foo***
指向foo**
)是不必要的;只是按价值复制(除了上面的注释)一个好的旧1D数组实际上应该足够了
在free
malloc
答案 1 :(得分:1)
您收到的警告是因为您忘记了#include <stdlib.h>
,因此未声明malloc
,因此编译器假定它应该返回int
。这可能会导致各种有趣的问题。 (你应该删除那些演员。)
另一个问题是:(*arr[1])->i = 3;
后缀运算符(如[]
)绑定比前缀运算符更严格(如*
),因此*arr[1]
解析为*(arr[1])
。
您可以编写(*arr)[1]->i
来解决此问题,但事实证明,您的函数实际上从未修改*arr
,因此没有理由通过arr
(另一个{{1}主要的那个)的地址。就这样做:
arr
并将其称为void doSomething(foo **arr)
{
arr[1]->i = 3;
}
。