尝试索引函数

时间:2015-08-29 20:43:35

标签: c arrays pointers

我试图用数组(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;
}

2 个答案:

答案 0 :(得分:2)

你的问题就在这一行

(*arr[1])->i = 3;

由于下标运营商的评估precedes是解除引用的评估,因此它等同于以下内容:

(*(arr[1]))->i = 3;

这显然是错误的。你需要

(*arr)[1]->i = 3;

因此

注意:

  • do not cast the result of 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; }