似乎我仍然没有得到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() {
}
我该怎么做?
提前谢谢!
答案 0 :(得分:3)
您的initj()
函数将j
设置为指向本地数组。该数组的生命周期仅限于函数调用本身,一旦函数返回,指针就不再有效。因此,尝试取消引用j
是undefined behaviour。
我不知道你想要做什么,但有三种可能性:
i
。i
声明为static
。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
是一个悬空指针。