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

如何在给定代码中正确使用malloc以避免程序崩溃?

问题分析与修复方案

1. sl_shallow_copy函数的核心问题

你的sl_shallow_copy只分配了一个链表节点,却试图遍历整个原链表,直接导致程序崩溃:

  • 初始分配的shallow节点的next是未初始化的垃圾值,第一次循环后shallow = shallow->next会指向无效内存;
  • 没有为原链表的每个元素分配新节点,无法复制完整的链表结构;
  • 最终返回的是遍历到末尾的无效指针,而非拷贝链表的头节点。

修复后的sl_shallow_copy:

slist *sl_shallow_copy(slist *strings) {
    slist *head = NULL;
    slist **tail = &head; // 用指针的指针跟踪链表尾部
    
    while (strings != NULL) {
        // 为每个元素分配新节点
        *tail = malloc(sizeof(slist));
        (*tail)->s = strings->s; // 浅拷贝:仅复制字符串指针
        (*tail)->next = NULL;    // 初始化next为NULL
        
        tail = &((*tail)->next); // 移动尾部指针到下一个位置
        strings = strings->next;
    }
    return head;
}

2. sl_free函数的问题

你的sl_free会释放每个节点的s指针,但如果是浅拷贝链表,s指针与原链表共享内存,会引发:

  • 原链表的s指针变成悬空指针;
  • 若原链表也调用sl_free,会触发双重释放崩溃。

解决方案是提供两种释放函数适配不同场景:

// 仅释放链表节点(用于浅拷贝链表,不释放共享的字符串)
void sl_free_shallow(slist *strings) {
    if (strings != NULL) {
        sl_free_shallow(strings->next);
        free(strings);
    }
}

// 释放链表节点和字符串(用于拥有字符串所有权的链表,比如sl_cons创建的链表,前提是s由malloc分配)
void sl_free_deep(slist *strings) {
    if (strings != NULL) {
        sl_free_deep(strings->next);
        free(strings->s);
        free(strings);
    }
}

3. 额外注意事项

  • 调用sl_cons时,确保传入的s是malloc分配的内存,否则sl_free_deep会因释放非堆内存崩溃;
  • 无需对malloc的返回值强制类型转换(C中不必要,还可能隐藏stdlib.h未包含的错误);
  • 建议检查malloc返回值是否为NULL,避免内存分配失败引发后续错误。

内容的提问来源于stack exchange,提问作者DevFish

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 04:05:33