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

C语言中strdup与strcat使用异常:堆缓冲区溢出问题排查

堆缓冲区溢出问题分析与修复

你的代码触发堆缓冲区溢出的核心原因:

  • strdup(server->vhost.root_dir)仅分配了刚好容纳root_dir字符串(含末尾\0)的内存空间
  • strcat(path, request.Request_target)需要在path现有内存基础上,额外容纳Request_target的所有字符加结束符,但当前path没有多余空间,直接写入会越界,触发堆溢出

从AddressSanitizer报错也能验证:分配的30字节区域刚好到0x6030000002ce,而你要写入的位置就是这个地址,刚好超出分配的内存范围。

修复方案

必须先计算两个字符串的总长度,分配足够内存后再拼接,以下是两种可靠实现:

方式1:手动计算长度分配内存

// 计算总长度:root_dir长度 + Request_target长度 + 1(结束符)
size_t total_len = strlen(server->vhost.root_dir) + strlen(request.Request_target) + 1;
char *path = malloc(total_len);
if (path == NULL) {
    return;
}
// 先复制root_dir,再拼接Request_target
strcpy(path, server->vhost.root_dir);
strcat(path, request.Request_target);

// 注意:使用完path后需调用free(path)避免内存泄漏

方式2:用snprintf更安全(推荐)

snprintf可直接指定缓冲区大小,规避手动拼接的风险:

size_t root_len = strlen(server->vhost.root_dir);
size_t target_len = strlen(request.Request_target);
size_t total_len = root_len + target_len + 1;
char *path = malloc(total_len);
if (path == NULL) {
    return;
}
// 一次性完成拼接
snprintf(path, total_len, "%s%s", server->vhost.root_dir, request.Request_target);

// 使用完后调用free(path)

另外注意:原代码中strcat的返回值永远不会是NULL,所以if (path == NULL)的判断完全无效,可直接删除。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 19:10:35