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

为何C语言中用strcpy给小数组赋值却输出完整字符串?

关于C语言strcpy缓冲区溢出导致输出异常的问题
#include <stdio.h>
#include <string.h>

int main(void) {

    char s1[6] = "Hello";
    char s2[3];

    strcpy(s2, s1);

    printf("%s\n", s2);
    
    return 0;
}

我编写了上述C语言代码,原本预期输出要么是错误,要么s2的值为{'H', 'e', '\0'},但实际输出却和s1一样是Hello。明明s2仅能容纳3个字符,长度小于s1,请问这是为什么?


  • strcpy的无边界复制特性:strcpy函数的工作逻辑是从源字符串起始位置逐个复制字符,直到遇到'\0'终止符才停止,它完全不会检查目标缓冲区的剩余空间。你的s1包含'H'、'e'、'l'、'l'、'o'、'\0'共6个字符,调用strcpy(s2, s1)时,这6个字符会被全部写入s2指向的内存区域——但s2仅分配了3字节的存储空间,这直接触发了缓冲区溢出。

  • 内存布局的巧合:在你的程序运行环境中,s1很可能被编译器分配在s2相邻的内存位置(栈上的变量布局通常由编译器按声明顺序排列)。溢出的字符直接覆盖了s2之后的内存区域,导致从s2起始地址开始的连续内存里,完整存储了"Hello\0"这串数据。

  • printf的输出规则:printf("%s")是从指定的起始地址开始输出字符,直到遇到'\0'才停止。虽然s2本身只分配了3字节,但溢出后其起始地址往后的内存已经有完整的字符串和终止符,所以printf会输出全部字符,看起来就像s2存储了整个Hello。

  • 本质是未定义行为:这种情况属于C语言的未定义行为——C标准没有规定缓冲区溢出后程序的运行结果,不同编译器、不同操作系统甚至不同运行次数下,结果都可能不同:可能输出乱码、程序崩溃,也可能像你这次一样看似“正常”。这种行为完全不可靠,随时可能引发严重问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 17:05:51