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

已释放strdup分配内存仍出现内存泄漏,求排查原因

问题分析与修复

你的代码中导致strdup相关内存泄漏的核心问题及修复方案如下:

核心问题

1. main函数的无限循环导致链表内存永远无法释放

main里的while(1)是无限循环,除非程序被强制终止(如信号中断),否则循环后的free_linkedlist()永远不会执行。所有添加到链表的节点(包括strdup分配的cmd_name内存)都无法在程序正常结束时释放,必然会被检测为内存泄漏。

2. remove_background_process的逻辑存在冗余(非泄漏直接原因,但可优化)

当前删除节点的逻辑重复了内存释放代码,且虽能正确释放单个节点的内存,但如果程序未通过该函数清空所有节点,又因死循环无法执行free_linkedlist(),泄漏问题依然存在。

修复方案

方案一:让程序能正常退出并执行内存释放

在循环中添加退出条件,比如捕获退出信号或检测用户指令,确保free_linkedlist()能被执行:

#include <signal.h>

static volatile sig_atomic_t exit_flag = 0;

void handle_sigint(int sig) {
    exit_flag = 1;
}

int main() {
    signal(SIGINT, handle_sigint); // 捕获Ctrl+C信号触发退出

    while (!exit_flag) {
        // 原有业务逻辑
        // execute_pipeline(l);
    }

    // 正常退出时释放所有内存
    free_linkedlist();
    return 0;
}

方案二:优化remove_background_process的内存释放逻辑

简化重复代码,确保节点内存释放逻辑统一:

void remove_background_process(int pid) {
    struct background_processes *current = head;
    struct background_processes *prev = NULL;
    while (current != NULL) {
        if (pid == current->pid) {
            struct background_processes *to_free = current;
            // 调整链表指针
            if (prev == NULL) {
                head = current->next;
            } else {
                prev->next = current->next;
            }
            // 释放内存(先释放strdup分配的字符串,再释放节点)
            free(to_free->cmd_name);
            free(to_free);
            // 继续遍历剩余节点
            current = (prev == NULL) ? head : prev->next;
        } else {
            prev = current;
            current = current->next;
        }
    }
}

额外建议

  • 检查strdup返回值:strdup内部调用malloc可能分配失败返回NULL,需添加错误处理避免后续崩溃:
current->cmd_name = strdup(name);
if (current->cmd_name == NULL) {
    free(current); // 释放已分配的节点
    exit(EXIT_FAILURE);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 07:27:30