arduino简单string入门——如何正确的使用arduino字符串以避免出现内存问题

对于只有少量字符串的小草图,只要方便使用它们即可

对于包含少量字符串的小型草图,只需使用它们即可。好消息是,如果您使用的是 UNO 或 Mega2560 或其他基于 AVR 的主板,那么使用字符串非常安全,即使内存不足也不会导致主板崩溃如果内存不足,您将无法获得期望的字符串中的所有文本。程序将继续运行。请参见下面的UNO 耗尽堆内存时会发生什么
其他主板将拥有更多可用内存,因此使用少量字符串不太可能出现内存问题。
无论如何,请仔细阅读Arduino 文档中有关字符串加法运算符的内容,以避免在使用字符串 + 运算符时出现常见的编码错误。

String 库中有一些不为人知的错误,可能会导致您的草图崩溃,否则在 AVR 板上使用String不会使您的主板崩溃/重新启动。此版本的 WString.cpp和此版本的 WString.h修复了这些错误。只需将其复制到 arduino ...\hardware\arduino\avr\cores 目录中的 WString.cpp 和 WString.h 和 Stream.cpp 上即可。Arduino 的未来版本将包含对这些错误的修复。

 

对于大型草图或大量字符串,或者如果你认为你有内存问题

 

如果您有一个很大的草图,其中包含大量字符串,或者您担心可能存在内存问题,那么遵循以下指南将使您的草图可靠且安全。

 

 

Arduino 字符串使用指南

 

1)

完全不要使用 String + 运算符,C/C++ 很容易导致代码错误。避免使用 String(...) 构造函数,因为它们会创建短暂的临时字符串。使用 = 和 += 运算符或 concat(),如 result += “str”; result += 'c'; result += number; 等。请参阅最小化内存使用量

2)

将长寿命字符串声明为全局变量,并在setup()中保留 () 空间 从最小到最大。检查最后一个最大保留 ()的返回值,以确保有足够的内存容纳所有字符串

3

)如果您已经在loop()方法 中创建了字符串,它们是长期存在的,请将它们移动到全局变量并重复步骤 1。

4)

将所有字符串参数作为const String& 传递给方法。对于结果,传递一个String& 结果,该方法可以使用结果进行更新。即 void strProcessing(const String &input1, const String &input2, ,, String &result) {..} 请参阅使用 String& 作为参数

5)

将 IDE 文件 → 首选项 编译器警告设置为全部,并观察编译窗口中的警告:将“const String”作为“this”参数传递会丢弃限定符 [-fpermissive]消息。这表示您正在尝试修改 const String&参数。

6)

使用小巧紧凑的方法进行字符串处理。在这些方法中,优先使用本地字符串而不是本地 char[]。这些方法将在退出时完全恢复其本地字符串和其他变量使用的所有堆和堆栈。请参阅String 与 char[]

7 )

要监控低内存和碎片,请至少向最后一个最大的字符串保留 ()添加StringReserveCheck 根据需要向其他字符串添加StringReserveCheck 。请参阅 使用StringReserveCheck(下载并安装StringReserveCheck.zip

8)

如果您的 Arduino 程序使用 Web,例如 ESP32 / EPS8266 webserver/httpClient,则底层 Web 支持库已经使用了大量字符串。如果您的项目需要长时间运行,请添加定期自动重启。请参阅ESP32/ESP8266 添加定期自动重启

9)

不要在中断例程中调用字符串方法。字符串使用 malloc/realloc 从堆中获取内存来存储字符。UNO、Mega2560 等(AVR 处理器和其他处理器)上的 malloc/realloc 并非设计为从主循环调用,然后中断并再次调用(可重入调用)。结果是由于 malloc/realloc 无法跟踪正在发生的事情而导致崩溃,除非您添加额外的“保护”代码来阻止它。

 

Arduino 字符串一直受到负面报道,因为它们会使用额外的内存进行复制,并且会造成内存碎片。这些最终会消耗所有可用内存,并导致微控制器出现错误并重新启动。本教程将向您展示如何在使用 Arduino 字符串时避免这两个内存问题。通常建议的解决方案是用低级 c 字符串方法和 char[] 操作替换 Arduino 字符串。C 字符串方法和 char[] 操作很容易出现编码错误(请参阅下面的为什么不应该使用 c-cstring 方法),因此不应使用。Arduino 字符串所基于的 C++ 字符串库旨在避免由 c 字符串和 char[] 操作引起的系统性编码问题。应始终优先使用 Arduino 字符串或SafeString 库,而不是低级 c 字符串方法或 char[] 操作。

好消息是,如果您使用的是 UNO 或 Mega2560 或其他基于 AVR 的主板,那么使用字符串是非常安全的,即使内存不足也是如此。如果内存不足,您将无法获得字符串中您期望的所有文本。程序将继续运行。请参见下面的UNO 用尽堆内存时会发生什么

如果字符串需要更多空间来存放文本,它将尝试分配更多内存。如果您想完全控制内存使用情况,或者您正在使用返回 char* 的库,或者您想要一组更丰富的读取器、解析器和文本函数,或者您想要详细的调试/错误消息,那么您可以从 Arduino 库管理器安装SafeString 库。请参阅下面的SafeString 替代方案。

 

posted @ 2025-01-26 23:52  mcwhirr  阅读(225)  评论(0)    收藏  举报