我试图做一些与数组(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 %dn",arr[1]->i );
doSomething(&arr);
printf("After %dn",arr[1]->i );
return 0;
}
void doSomething(foo ***arr)
{
(*arr[1])->i = 3;
}
你的问题是行
(*arr[1])->i = 3;
由于下标操作符的求值在解引用操作符的求值之前,因此它等价于以下操作:
(*(arr[1]))->i = 3;
这显然是错误的。你需要
(*arr)[1]->i = 3;
因此。指出:
- 不强制转换
malloc
的结果 - 添加
#include <stdlib.h>
来解决警告 - 添加额外的间接级别(
foo***
指向foo**
)是不必要的;直接复制 (除了上面的注释)一个好的旧1D数组实际上应该足够在你的情况下
在
malloc
之后呼叫free
您得到的警告是因为您忘记了#include <stdlib.h>
,所以没有声明malloc
,所以编译器认为它应该返回int
。这可能会导致各种有趣的问题。(并且您应该删除这些强制类型转换。)
另一个问题在这一行:(*arr[1])->i = 3;
后缀操作符(如[]
)比前缀操作符(如*
)绑定更紧密,因此*arr[1]
解析为*(arr[1])
。
您可以编写(*arr)[1]->i
来解决这个问题,但事实证明,您的函数实际上从未修改*arr
,因此没有理由将arr
(另一个arr
,在main中)的地址传递给它。只需这样做:
void doSomething(foo **arr)
{
arr[1]->i = 3;
}
并命名为doSomething(arr)