这个问题类似于这个问题:Serial.println changes return value of function (Arduino)
我有一个函数test(byte _b[])
,它接收一个字节数组并使用本地临时字节数组更改其值。当函数test
返回时,该本地字节数组被销毁,因此调用者不应该能够访问它。但是,Serial.println()使调用者可以访问本地数组。 为什么?这有点像内存泄漏吗?
代码(在Arduino 1.6.12,64位Debian Jessie中测试):
uint32_t timer;
void setup () {
Serial.begin(57600);
Serial.println("init");
}
void loop () {
if (millis() > timer) {
timer = millis() + 1000;
// many bytes need escaping, so we better use the URLencode function
byte testarray[3];
test(testarray);
Serial.print("testing: ");
Serial.println((char *) testarray);
Serial.println("---------");
}
}
void test(byte _b[]) {
byte c[4];
c[0] = 95; c[1] = 48; c[2] = 55; c[3] = 0;
_b = c;
Serial.println((char *) c); // MARKED: this is the line that causes the unexpected behaviour
}
使用MARKED行,我得到以下输出:
init
_07
testing: _07
---------
_07
testing: _07
---------
没有MARKED线,我明白了:
init
testing:
---------
testing:
---------
testing:
---------
testing:
---------
testing:
---------
答案 0 :(得分:0)
将未初始化的字节传递给函数:
byte testarray[3];
// ... code that does not write to testarray ...
Serial.println((char *) testarray);
这会导致undefined behaviour;使用未初始化值的一个常见影响是它们似乎包含最近由程序的其他部分使用的一些其他内容。
请注意,您将特定行标记为导致意外行为,但该行可正常工作。并输出_07
。然后,当执行到达未定义的行为行时,此实例中的表现形式也是输出_07
。
在函数test
内部,您可能忽略了一些事情:
void test(byte * _b)
相同。 _b
是指向testarray
的第一个元素的指针。_b
对于复制初始化_b
的任何参数都不会产生任何影响。 (要清楚,_b
是一个指针 - 我们正在讨论指针,而不是_b
可能指向的任何内容。所以这一行:
_b = c;
更改局部变量_b
指向的位置,并且不会更改testarray
的任何内容。