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

Valgrind显示7次内存分配7次释放仍存在内存泄漏问题求解

问题原因分析

内存泄漏的核心原因是你调用free()时传入的不是getline()动态分配的内存起始地址:

  • getline() 接口会自动在堆上分配内存存储读取的行内容,返回的原始堆内存起始地址存在你定义的buffer变量中。
  • 你后续执行了buffer += 5、buffer += 6以及遍历过程中的buffer++操作,此时buffer指针已经偏移到了分配内存的中间位置。free()只允许传入malloc/realloc返回的原始起始地址,传入偏移后的地址属于未定义行为,系统不会释放对应的整块内存,因此产生泄漏。

至于Valgrind显示7次分配7次释放仍有泄漏的疑问:你两次释放偏移地址的操作属于无效释放,Valgrind会统计为释放动作,但不会对应到你两次getline产生的有效分配块,因此总计数匹配但仍存在两块未被正确释放的内存。

其他潜在问题
  1. 文件打开失败后没有直接返回,后续仍执行getline、fclose操作,会触发空指针访问崩溃。
  2. 字符串读取没有加边界检查,存在数组越界风险。
修复方案

不要修改getline返回的原始buffer指针,用临时指针做偏移操作即可,参考修改后的代码:

int get_num_vars(char* path) {
        FILE* fptr;
        size_t length = 0;
        char* buffer = NULL; // 初始化空指针避免未定义行为
        char num_vars_str[3];

        fptr = fopen(path, "r");
        if(fptr == NULL) {
                printf("Error opening file.\n");
                return -1; // 打开失败直接返回
        }

        getline(&buffer, &length, fptr);
        char* curr = buffer +5; // 用临时指针操作,不修改原始buffer

        int counter = 0;
        while(*curr != '\n' && counter < 2) { // 加边界检查避免越界
                num_vars_str[counter++] = *curr++;
        }
        num_vars_str[counter] = '\0';
        fclose(fptr);
        free(buffer); // 释放原始起始地址
        return atoi(num_vars_str);
}

get_num_nodes函数按相同逻辑修改即可:用临时指针做偏移和遍历,始终保留原始buffer地址用于释放,同时补充文件打开失败的错误处理逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 14:06:03