指向数组的全局指针
看来我还是没有正确理解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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的
initj()
函数将j
设置为指向本地数组。该数组的生命周期仅限于函数调用本身,一旦函数返回,指针就不再有效。因此,尝试取消引用j
是未定义行为。我不知道你到底想做什么,但三种可能性是:
i
。i
声明为static
。malloc
动态分配数组(可能不适合嵌入式平台)。Your
initj()
function setsj
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 dereferencej
is therefore undefined behaviour.I don't know exactly what you want to do, but three possibilities are:
i
at global scope instead.i
asstatic
.malloc
(maybe unsuitable for an embedded platform).这是因为数组
i[2]
是initj()
函数的本地数组。因此,一旦函数返回,它就不再有效。所以指针j
变成了一个悬空指针。所以你调用了未定义的行为。
至于为什么这两行的行为是这样的:
即使值丢失了,它们仍然恰好在堆栈上。因此,当您在调用
Serial.println
之前访问它时,您将获得“正确”的值。但该函数调用最终会覆盖堆栈。因此,在第二次调用时,它给出了错误的值。但无论如何,这仍然是未定义的行为。任何事情都可以发生。
要解决此问题,您需要将值放入
setup()
函数可见的范围内。您可以全局声明i[2]
,也可以在setup()
中声明并将其传递给initj()
函数。您还可以使用
malloc()
在堆内存中动态分配数组。 (并确保稍后使用free()
释放它)This because the array
i[2]
is local to theinitj()
function. Therefore, once the function returns, it is no longer valid. So the pointerj
becomes a dangling pointer.So you have invoked undefined behavior.
As for why these two lines behave the way they do:
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 declarei[2]
globally, or insetup()
and pass it into theinitj()
function.You can also dynamically allocate the array in heap memory with
malloc()
. (and be sure to free it later withfree()
)一旦 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 ofi
toj
. So, in setup(),j
is a dangling pointer.