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

C语言变量意外被修改求助:数组越界引发地址覆盖?

变量意外被覆盖的原因分析

问题背景

在Code::Blocks中编写C语言代码时,发现变量goal会被num[2]的值意外修改。调整goal的声明位置(单独行声明或放在num数组之后)可临时解决问题,但需要明确地址重叠的原因,以及这是否是C语言常见bug或设备问题。

初始代码

#include <stdio.h>

int main() {
    int i, n, goal, num[2], sum;
    printf("Input n: "); scanf("%d", &n);

    for (i = 1; i <= n; i++) {
        scanf("%d %d %d %d", &goal, &num[0], &num[1], &num[2]); // 获取整数
        if (num[0] != num[1] && num[1] != num[2] && num[2] != num[0]) { // 检查是否全唯一
            sum = num[0] + num[1] + num[2];
            if (goal == sum)
                printf("Proper triplet");
            else
                printf("Not a good triplet");
        } else
            printf("Not a good triplet");
        printf("\n");
    }
}

调试后的代码

#include <stdio.h>

int main() {
    int i, n, goal, sum, num[2];

    printf("Input n: "); scanf("%d", &n);

    for (i = 1; i <= n; i++) {
        scanf("%d %d %d %d", &goal, &num[0], &num[1], &num[2]); // 获取整数
        printf("%d %d %d", num[0], num[1], num[2]); printf("\n\n");

        printf("%d", goal); printf("\n\n");

        if (num[0] != num[1] && num[1] != num[2] && num[2] != num[0]) { // 检查是否全唯一
            sum = num[0] + num[1] + num[2];
            if (goal == sum)
                printf("Proper triplet");
            else
                printf("Not a good triplet %d %d", goal, sum);
        } else
            printf("Not a good triplet");
        printf("\n");
    }
}

核心原因

这既不是C语言的bug,也不是设备问题,完全是数组越界访问引发的未定义行为:

  • 你声明的num数组长度为2,仅能通过num[0]和num[1]访问有效元素,代码中频繁访问num[2]属于明确的数组越界操作。
  • C语言标准不要求编译器检查数组越界,程序会直接向数组内存之后的地址写入数据。
  • 栈内存通常从高地址向低地址分配变量,当声明顺序为int i, n, goal, num[2], sum;时,goal的内存地址恰好与num[2]的越界地址重叠(数组元素按低到高排列,num[2]是数组末尾之后的第一个位置),因此写入num[2]时会直接覆盖goal的值。
  • 调整变量声明顺序后,goal的地址不再与num[2]的越界地址重叠,覆盖现象暂时消失,但这只是巧合——数组越界的根本问题未解决,后续仍可能触发崩溃、数据错乱等不可预测的错误。

正确修复方案

将num数组的长度修改为3,确保能容纳3个元素,消除越界访问:

#include <stdio.h>

int main() {
    int i, n, goal, num[3], sum; // 数组长度改为3
    printf("Input n: "); scanf("%d", &n);

    for (i = 1; i <= n; i++) {
        scanf("%d %d %d %d", &goal, &num[0], &num[1], &num[2]); // 现在访问num[2]合法
        if (num[0] != num[1] && num[1] != num[2] && num[2] != num[0]) {
            sum = num[0] + num[1] + num[2];
            if (goal == sum)
                printf("Proper triplet");
            else
                printf("Not a good triplet");
        } else
            printf("Not a good triplet");
        printf("\n");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 05:33:17