C语言先声明可变长度数组后输入k,元素≥5报段错误如何解决?
段错误出现原因
- 核心问题是变长数组定义的时序错误:你在代码中先使用未初始化的局部变量
k作为长度定义了变长数组numbers,此时k是栈内存中残留的随机垃圾值,数组实际分配的空间大小和你后续通过scanf输入的k没有任何关联。 - 小数值k运行正常是偶发现象:当你输入的k小于5时,输入的数值大概率小于
k的随机垃圾值,写入数组的元素没有超出实际分配的内存边界,因此不会触发异常;当输入k≥5时,写入的元素数量超过了数组实际分配的空间,发生栈缓冲区溢出,访问到了受保护的内存区域,因此触发段错误。
修复方案
你可以选择以下任意一种方案修复:
方案1:调整变量定义顺序(适用支持C99及以上标准的编译器,MacOS默认Clang编译器支持)
只需要把变长数组的定义移动到scanf读取k之后即可,修复后代码如下:
#include <stdio.h> int main() { int k, i, n; // 先读取k的有效值 printf("Introduceti k: "); scanf("%d", &k); // 再用确定的k值定义变长数组 int numbers[k]; for (i = 0; i < k; i = i + 1) { printf("Introduceti %d numar: ", i+1); scanf("%d", &n); numbers[i] = n; } printf("%d", numbers[k-1]); return 0; }
注:原代码中声明的j、smallest变量未使用,可以直接删除。
方案2:使用动态内存分配(兼容所有C标准编译器)
如果需要兼容不支持变长数组的编译器,可以使用malloc在堆上申请内存空间,使用完成后手动释放即可,修复后代码如下:
#include <stdio.h> #include <stdlib.h> int main() { int k, i, n; int *numbers; printf("Introduceti k: "); scanf("%d", &k); // 动态申请k个int大小的内存 numbers = (int *)malloc(sizeof(int) * k); // 内存申请失败判断 if (numbers == NULL) { printf("内存申请失败"); return 1; } for (i = 0; i < k; i = i + 1) { printf("Introduceti %d numar: ", i+1); scanf("%d", &n); numbers[i] = n; } printf("%d", numbers[k-1]); // 释放申请的内存 free(numbers); return 0; }
内容的提问来源于stack exchange,提问作者Vlad-Sebastian Cretu
相关产品推荐
相关产品推荐

