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

C语言HTML客户端代码内存泄漏排查求助(附代码与ASAN报告)

排查strndup引发的C语言内存泄漏及修复建议

核心原因分析

strndup函数会从堆上分配内存存储复制后的字符串,必须显式调用free()释放,如果分配后没有对应的释放操作,就会触发直接内存泄漏。AddressSanitizer的报告已经明确指向strndup的调用点,你需要从这些调用的上下文入手排查。

排查步骤

  • 从AddressSanitizer报告中提取strndup的调用栈,确定这两处调用分别对应HTTP响应解析的哪个环节(比如解析响应头字段、提取响应体片段等)。
  • 跟踪每个strndup返回的指针:
    • 是否被存入结构体、全局变量或其他持久化存储中?
    • 该存储对象在使用完毕后,是否有对应的内存清理逻辑?
    • 是否存在错误处理分支,导致指针未被释放就提前退出函数?

修复建议

1. 严格配对分配与释放

确保每个strndup调用都有对应的free操作,示例如下:

// 分配内存
char* parsed_field = strndup(source_buf, field_len);
if (parsed_field == NULL) {
    // 内存分配失败的错误处理
    return -1;
}

// 使用parsed_field处理业务逻辑...

// 使用完成后释放内存
free(parsed_field);
parsed_field = NULL; // 避免野指针

2. 结构体关联内存的统一清理

如果strndup的结果被存入自定义结构体,需为结构体编写专门的清理函数:

typedef struct {
    char* header_key;
    char* header_value;
} HttpResponseHeader;

// 清理HttpResponseHeader的所有动态分配内存
void http_response_header_free(HttpResponseHeader* header) {
    if (header == NULL) return;
    free(header->header_key);
    free(header->header_value);
    header->header_key = NULL;
    header->header_value = NULL;
}

当结构体不再被使用时,调用该清理函数完成内存释放。

3. 补全错误分支的内存释放

特别注意错误处理路径中是否遗漏了内存释放:

char* extract_response_status(const char* response_line) {
    char* status_str = strndup(response_line, 3);
    if (status_str == NULL) {
        return NULL;
    }

    if (!is_valid_status_code(status_str)) {
        // 错误分支必须先释放内存再返回,否则触发泄漏
        free(status_str);
        return NULL;
    }

    return status_str;
}

4. 利用AddressSanitizer精准定位

如果仍不确定泄漏位置,可以通过以下参数生成更详细的泄漏报告:

ASAN_OPTIONS=detect_leaks=1:log_path=asan_leak_report.txt ./your_html_client

报告中会包含泄漏内存的分配栈、内存大小等细节,帮助快速锁定问题代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 16:20:07