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

C++中扫描数组时已读取的变量n被意外修改是什么原因?

C++变量n被意外修改的问题分析
  • 第一处错误是变量声明顺序错误:你在n还未被赋值的情况下就声明了变长数组arr[n]。此时n是未初始化的局部变量,存储的是栈上的随机垃圾值,数组arr的长度是基于这个随机值确定的,后续你通过scanf给n赋值为4并不会改变已经声明的arr的长度。
  • 第二处错误是使用了非标准C特性:变长数组(VLA)是C99的标准特性,C标准从未支持该用法,仅部分编译器(如GCC)通过扩展支持,其行为本身就没有标准保障。
  • 最终导致n被修改的直接原因是栈缓冲区溢出:如果声明时n的随机值小于4,那么arr的实际长度小于4,你循环给arr[0]~arr[3]赋值时就发生了数组越界。局部变量n和arr都存储在栈空间上,越界写入的数组元素刚好覆盖了n对应的内存地址,而你最后一次写入的元素值是2,所以n的值就被意外改成了2。

修复方案

写法1(符合C++标准,兼容性最好,推荐)

使用标准库vector存储数组,无需依赖编译器扩展:

#include <cstdio>
#include <vector>
using namespace std;

int main()
{
    int n;
    scanf("%d", &n);
    vector<int> arr(n); // 先确定n的值,再初始化vector
    printf("%d \n", n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
        printf("%d ", arr[i]);
        printf("n=%d ", n);
    }
    printf("\n%d", n);
    return 0;
}

写法2(仅支持带VLA扩展的编译器)

调整变量声明顺序,先读取n的值,再声明变长数组:

#include <cstdio>
using namespace std;

int main()
{
    int n;
    scanf("%d", &n); // 先给n赋值
    int arr[n]; // 再声明变长数组
    printf("%d \n", n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
        printf("%d ", arr[i]);
        printf("n=%d ", n);
    }
    printf("\n%d", n);
    return 0;
}

内容的提问来源于stack exchange,提问作者Ruadh Mac Cárthaigh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 22:45:02