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

为什么向2字节栈缓冲区写入3字节时GCC和Valgrind均不报错?

问题原因解答

1. GCC无警告的原因

-Wall -Wextra 编译参数默认不会启用静态缓冲区溢出检测逻辑,GCC仅在开启 -Warray-bounds 编译选项且配合 -O1 及以上优化等级时,才会对编译期可识别的数组越界操作输出警告。
你代码中memcpy的拷贝长度是运行时通过strlen(x1)计算得到的,默认静态检查不会深入推导运行时的长度取值,因此不会触发警告。

2. Valgrind默认无报错的原因

你默认使用的Valgrind Memcheck工具,检测范围仅覆盖堆内存(即malloc/realloc/free等动态分配的内存)的越界访问、内存泄漏、非法释放等问题。
你代码中的in_buffer和x1都是栈上分配的局部变量,你越界写入的1字节刚好落在当前函数栈帧内部的x1数组存储空间内,这部分地址属于进程合法可访问的栈空间:

  • 操作系统不会触发段错误
  • Memcheck不会将其识别为非法内存访问,因此没有报错
    如果需要检测栈/全局数组的越界问题,可以使用Valgrind的SGCheck实验性工具,运行命令为valgrind --tool=exp-sgcheck ./a.out,即可检测到本次栈越界错误。

3. 代码存在的实际风险

这段代码属于典型的栈缓冲区溢出,是C语言标准明确的未定义行为,当前无报错不代表逻辑合法:

  • 你运行输出的abcbc已经是异常结果:memcpy写入3字节到仅2字节的in_buffer后,in_buffer末尾没有字符串终止符\0,printf读取字符串时会一直向后遍历相邻的x1存储区域,直到遇到\0才停止,因此输出了超出预期的内容。
  • 该未定义行为在不同编译环境、不同系统上表现完全不确定,可能直接崩溃、可能输出异常内容,极端场景下会被利用进行栈溢出攻击。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 23:15:04