You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 08:31:22