在函数中尝试索引指针到指针时出现段错误



我试图做一些与数组(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)

最新更新