尝试将指针指向函数中的指针时的Segfault
我正在尝试使用数组(malloc-ed),即自定义结构的arr
。 通过引用函数传递数组。 每当我在运行时尝试索引除函数中的arr[0]
以外的任何东西时,我会得到一个段错误(例如(*arr[1])->i = 3;
)。 为什么会这样?
完整的源代码是:
#include #include #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 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; }
你的问题就在于此
(*arr[1])->i = 3;
由于下标运算符的评估先于解除引用的评估,因此它等同于以下内容:
(*(arr[1]))->i = 3;
这显然是错误的。 你需要
(*arr)[1]->i = 3;
因此。
笔记:
- 不要
malloc
的结果 - 添加
#include
来解决警告 - 添加额外级别的间接(
foo***
指向foo**
)是不必要的; 只是按价值复制 -
(除了上面的注释)一个好的旧1D数组实际上应该足够了
-
在
malloc
之后free
拨打电话
你得到的警告是因为你忘了#include
,所以没有声明malloc
,所以编译器假定它应该返回int
。 这可能会导致各种有趣的问题。 (你应该删除那些演员。)
另一个问题是这一行: (*arr[1])->i = 3;
后缀运算符(如[]
)绑定比前缀运算符更紧(如*
),因此*arr[1]
解析为*(arr[1])
。
您可以编写(*arr)[1]->i
来修复此问题,但事实certificate,您的函数实际上从未修改过*arr
,因此没有理由传递arr
(另一个arr
,主要的那个)的地址。 这样做:
void doSomething(foo **arr) { arr[1]->i = 3; }
并称之为doSomething(arr)
。