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

C++字符数组打印结果不符预期及stack smashing detected错误原因

问题解答

代码、输入与输出

测试代码

#include <iostream>
using namespace std;

int main()
{
    int n;  // n=3
    cin >> n;
    char a[n];
    cin >> a;
    cout << a;
    return 0;
}

输入

3
Hello

输出

Hello

疑问1:为何输出是“Hello”而非“Hel”?

原因在于以下几点:

  1. cin >> a不做长度校验:这个输入操作会读取所有非空白字符(直到换行/空格),完全不管数组a的实际容量。你输入的"Hello"包含5个字符,加上C风格字符串必须的结束符\0,总共需要6字节空间,但数组只有3字节。
  2. 越界写入栈内存:数组a在栈上仅分配3字节,输入的'H'、'e'、'l'会存在数组内,剩下的'l'、'o'、'\0'直接写到数组之后的栈空间里——这属于未定义行为,内存被非法篡改,只是这次没触发崩溃。
  3. cout以\0为结束标志:输出C风格字符串时,cout会从数组起始地址开始读取字符,直到碰到\0才停止。由于输入时把\0写在了"Hello"的末尾,所以cout会把所有越界写入的字符都输出,最终显示"Hello"。

疑问2:定义为char a[3]时为何触发“stack smashing detected”?

这是编译器的栈保护机制在起作用:

  • 当你声明固定长度数组char a[3]时,GCC等编译器会在数组的栈空间末尾插入一个特殊的“金丝雀(Stack Canary)”值,用来检测栈溢出。
  • 输入"Hello"时,越界的字符会覆盖这个金丝雀值。
  • 程序执行到main函数末尾时,会检查金丝雀值是否被篡改。一旦发现异常,就会抛出"stack smashing detected"错误并终止程序——这是一种安全防护,防止栈溢出被恶意利用或导致程序崩溃。

而之前的变长数组char a[n]是C语言的扩展特性,部分编译器对VLA的栈保护支持不完善,所以没触发这个错误,但本质上同样是危险的越界写入行为。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 01:10:28