全局指向数组的指针

时间:2011-12-11 18:07:32

标签: c arrays global local arduino

似乎我仍然没有得到C中的指针。

我希望全局数组(指针)j的长度是动态的。

我有这个(Arduino)代码

unsigned int* j;

void setup() {

  Serial.begin(9600);

  initj();

  Serial.println(j[0]); //111 -> right
  Serial.println(j[0]); //768 -> wrong!
  Serial.println(j[1]); //32771 -> wrong!
}

void initj() {
  unsigned int i[2];
  i[0] = 111;
  i[1] = 222;

  j = i;

  Serial.println(j[0]); // 111 -> right
  Serial.println(j[1]); // 222 -> right
}

void loop() {
}

我该怎么做?

提前谢谢!

3 个答案:

答案 0 :(得分:3)

您的initj()函数将j设置为指向本地数组。该数组的生命周期仅限于函数调用本身,一旦函数返回,指针就不再有效。因此,尝试取消引用jundefined behaviour

我不知道你想要做什么,但有三种可能性:

  1. 改为在全球范围内声明i
  2. i声明为static
  3. 使用malloc动态分配数组(可能不适合嵌入式平台)。

答案 1 :(得分:2)

这是因为数组i[2]initj()函数的本地数组。因此,一旦函数返回,它就不再有效。所以指针j变成了悬空指针。

所以你调用了未定义的行为。

至于为什么这两条线的行为方式如下:

Serial.println(j[0]); //111 -> right
Serial.println(j[0]); //768 -> wrong!

即使值丢失,它们仍然恰好在堆栈中。因此,当您在致电Serial.println之前访问它时,您会获得“正确”的值。但是该函数调用最终会覆盖堆栈。所以在第二次调用时,它给出了错误的值。

但无论如何,它仍然是未定义的行为。任何事都可以发生。


要解决此问题,您需要将值放在setup()函数可见的范围内。您可以在全局或i[2]中声明setup()并将其传递到initj()函数。

您还可以使用malloc()在堆内存中动态分配数组。 (并确保稍后使用free()

释放它

答案 2 :(得分:1)

一旦initj完成,它的堆栈空间就被OS破坏(实际上,堆栈指针被移动,initj的地址不再可靠)。由于{1}存在于该堆栈空间中,i已消失。您只是将i的值复制到i。因此,在setup()中,j是一个悬空指针。