String
TLDR:当通过 arduinos类将浮点数打印到字符串时,我得到了一致的冻结。以前我用 sprintf 和 %f 得到了同样的冻结。我已经使用 PString 类解决了这个问题,但我想了解这个问题。
完整故事:我有一个相当大的用于 arduino SAMD 架构(MKRZero)的 C++ 代码库,最近在我很久没有接触的一行代码上开始冻结。sprintf
这是对with的调用%f
,它在以前的预期中奇怪地工作。在对 SO 和谷歌进行一些研究之后,我意识到 Arduino 不支持通过 sprintf 进行浮点格式化,并且在排除 dtostr (由于不在 AVR 上)之后,我尝试了 ArduinosString
类。这暂时解决了问题,但在使用一些不同的外部外围设备(可以连接和断开的 I2C 从机)测试系统后,冻结又出现了。所以完全相同的代码,但是由于不同的外围设备,它的部分被执行了一些差异。
代码库非常大(几 1000 行),我无法用一个简单的例子来重现。所以不幸的是,没有太多上下文,这些是失败的行:
for (int fieldIndex = 0; fieldIndex < totalFullDataPoints; fieldIndex++) {
char buffer[14];
Serial.println("foo");
// String floatString = String((float)data[fieldIndex], 2); // causes system to freeze
// String floatString = String((float)1024.46, 2); // causes system to freeze
String floatString = String((float)1024.46); // causes system to freeze
// String floatString = String("1024.46"); // works
Serial.println("bar"); // freezes before this
}
该错误非常不稳定,因为我可以通过修改代码中其他位置不相关的内容或从我的 arduino 断开传感器(I2C 从站)来使其无法触发。但是当它出现时,它是一致的,因为它每次运行都会发生。我什至有一个可以运行的代码版本 - 但是删除其中三行会导致它再次冻结:
String floatString = "14123.123";
Serial.println("Float String: ");
Serial.println(floatString);
我很确定这不是内存问题,据我所知,这不是指针或非终止字符串爆炸的情况。
由于这篇文章https://forum.arduino.cc/t/use-pstring-to-avoid-crashes-due- ,我最终使用了PString
s(https://github.com/boseji/PString-Arduino-lib ) to-string-sprintf-or-dtostrf-float-issues/230946但我很沮丧和好奇,为什么它在String
应该支持创建浮动时以这种看似随机的方式冻结。