似乎我仍然没有正确使用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() {
}

我该怎么做呢?

先感谢您!

===============>>#1 票数:3 已采纳

您的initj()函数将j设置为指向本地数组。 此数组的生存期仅限于函数调用本身,函数返回后,指针将不再有效。 因此,尝试取消引用j未定义的行为

我不确定您要做什么,但有三种可能:

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

===============>>#2 票数: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()将其free()

===============>>#3 票数:1

一旦完成了initj,它的堆栈空间就会被操作系统破坏(或者实际上是移动了堆栈指针,并且initj的地址不再可靠了)。 因为i存在于那个堆栈空间中,所以i走了。 ou只是将i的值复制到j 因此,在setup()中, j是一个悬空指针。

  ask by speendo translate from so

未解决问题?本站智能推荐:

关注微信公众号