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
相关产品推荐
相关产品推荐

