使用scanf向指针指向的内存输入整数时出现值异常的问题
指针越界与循环中断导致的赋值异常
先看这段出现问题的C代码:
int num = 0, k = 0; scanf("%d %d", &num, &k); int* A = # for (int i = 0; i < num; i++) { scanf("%d", &A[i]); //scanf("%d", A+i); }
需求与输入
想要把整数4 5 1 3 2存入指针A指向的“数组”中,输入内容为:
5 7 4 5 1 3 2
调试结果
但调试时内存中的值不符合预期:
*A 4 int *(A+1) 5 int *(A+2) 1 int *(A+3) 3 int *(A+4) -858993460 int *(A+5) -858993460 int
问题原因
- 内存空间不足:
int* A = #只是让A指向单个int变量num的地址,这块内存只能存1个int值,根本不是数组。后续给A[1]、A[2]等赋值属于越界访问内存,行为本身未定义。 - 循环提前终止:第一次循环给
A[0]赋值时,本质是修改了num的值(因为A[0]就是num)。原本num是5,赋值后变成4,循环条件i < num就变成i < 4,循环只执行4次(i从0到3),第5个输入值2完全没被读入,*(A+4)自然是未初始化的垃圾值(-858993460是VS环境下未初始化栈内存的默认值)。
根本解决方案
不能用单个变量的地址模拟数组,必须分配足够的内存空间:
方案1:动态内存分配(推荐,适配任意大小数组)
#include <stdlib.h> // 需包含malloc和free的头文件 int num = 0, k = 0; scanf("%d %d", &num, &k); // 分配能存储num个int的内存 int* A = (int*)malloc(num * sizeof(int)); if (A == NULL) { // 处理内存分配失败的逻辑 return 1; } for (int i = 0; i < num; i++) { scanf("%d", &A[i]); } // 使用完数组后释放内存,避免泄漏 free(A);
方案2:变长数组(C99及以上支持,适合小数组)
若编译器支持C99或更高标准,可直接在栈上声明变长数组:
int num = 0, k = 0; scanf("%d %d", &num, &k); int A[num]; // 根据输入的num确定数组大小 for (int i = 0; i < num; i++) { scanf("%d", &A[i]); }
注意:变长数组在栈上分配内存,若num过大会导致栈溢出,此时优先用动态分配。
内容的提问来源于stack exchange,提问作者Cheon SeockBeom
相关产品推荐
相关产品推荐

