指向数组的全局指针

发布于 2024-12-20 10:37:48 字数 525 浏览 1 评论 0原文

看来我还是没有正确理解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() {
}

我怎样才能正确地做到这一点?

先感谢您!

Seems like I still didn't get the pointers in C right.

I want the length of the global array (pointer) j being dynamic.

I have this (Arduino) code

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() {
}

How can I do this right?

Thank you in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

尴尬癌患者 2024-12-27 10:37:48

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

我不知道你到底想做什么,但三种可能性是:

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

Your initj() function sets j to point at a local array. The lifetime of this array is limited to the function call itself, as soon as the function returns, the pointer is no longer valid. Attempting to dereference j is therefore undefined behaviour.

I don't know exactly what you want to do, but three possibilities are:

  1. Declare i at global scope instead.
  2. Declare i as static.
  3. Dynamically allocate the array using malloc (maybe unsuitable for an embedded platform).
ぇ气 2024-12-27 10:37:48

这是因为数组 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() 释放它)

This because the array i[2] is local to the initj() function. Therefore, once the function returns, it is no longer valid. So the pointer j becomes a dangling pointer.

So you have invoked undefined behavior.

As for why these two lines behave the way they do:

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

Even though the values are lost, they still happen to be on the stack. So when you access it before you call Serial.println, you get the "right" value. But that function call ends up overwriting the stack. So on the second call, it gives the wrong value.

But in any case, it's still undefined behavior. Anything is allowed to happen.


To fix this, you need to put the values in a scope that is visible to the setup() function. You can either declare i[2] globally, or in setup() and pass it into the initj() function.

You can also dynamically allocate the array in heap memory with malloc(). (and be sure to free it later with free())

ぺ禁宫浮华殁 2024-12-27 10:37:48

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

Once initj is done, its stack space is destroyed by the OS (or actually, the stackpointer is moved and initj's addresses are not reliable anymore). Because i exists in that stack space, i is gone. And ou just copied the value of i to j. So, in setup(), j is a dangling pointer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文