Arduino中使用LinkedList存储char*的长期稳定性疑问
Arduino中LinkedList存储char*的内存问题
问题背景
我在Arduino中使用LinkedList库,希望存储"AA"、"AB"这类双字符项,且不愿使用Arduino框架提供的String类。最初用char*声明链表:
MyLinkedList::LinkedList<char *> _myList;
但加载列表的代码存在问题:
// 此处String来自外部函数 bool Languages::processHeader(String header) { char buffer[8]; const char delimiters[] = ","; char *token; char *ptr; char lang[3]; header.toCharArray(buffer, 8); // 索引 token = strtok_r(buffer, delimiters, &ptr); if (token == NULL) return false; while (token) { token = strtok_r(NULL, delimiters, &ptr); if (token == NULL) break; strncpy(lang, token, 2); _myList.add(lang); } return true; }
我清楚这段代码无法正常工作,原因:
- 每次循环中
lang的地址均相同,链表存储的都是同一个指针 lang是局部变量,函数退出后其内存会被覆盖
因此我修改了代码:
while (token) { token = strtok_r(NULL, delimiters, &ptr); if (token == NULL) break; char *lang = (char*) malloc(3); strncpy(lang, token, 2); lang[2] = '\0'; _myList.add(lang); }
测试后代码看似正常,但不清楚长期使用是否会引发bug,想了解潜在问题。
问题分析与解答
你修改后的代码逻辑是正确的,但存在内存泄漏这个核心风险,此外还有几个细节需要注意:
1. 内存泄漏风险
你通过malloc为每个字符串分配了3字节内存,但如果后续不对链表中的每个元素调用free()释放内存,这些内存会被永久占用。Arduino的RAM资源非常有限,长期运行后必然会耗尽内存,导致程序崩溃、行为异常。
2. 必须检查malloc返回值
Arduino的RAM很小,malloc可能因内存不足返回NULL。如果直接将NULL加入链表,后续访问该字符串时会触发程序崩溃,建议添加判断:
char *lang = (char*) malloc(3); if (lang == NULL) { // 处理内存分配失败,比如跳过当前项或返回错误 continue; }
3. 链表的正确清理方式
当你不再需要链表时,必须遍历每个元素手动释放内存,再清空链表。如果直接使用LinkedList的clear()方法,它只会移除链表中的指针,不会释放指针指向的内存,会直接导致内存泄漏。示例代码:
while (_myList.size() > 0) { char* item = _myList.remove(0); free(item); }
总结
只要你记得在合适的时机(比如链表不再使用时)手动释放每个malloc分配的内存,这段代码就能长期稳定运行;如果忽略内存释放,迟早会因为内存耗尽出现问题。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

