C语言用户定义数组大小异常:空数组声明引发运行错误
问题原因与解决方案
为什么你的代码会出现异常行为?
你写的int arr[] = {};是错误写法,C标准不允许空初始化的数组,即便部分编译器勉强接受,它也只会创建一个大小为0的空数组——这个数组没有任何可用存储空间。
当你后续通过read_array函数往arr[i]写入数据时,本质是在越界访问内存:写入的内容会覆盖栈上其他变量的内存空间(比如变量n的内存),甚至会访问到栈外不属于程序的内存区域。这就导致了各种不确定的异常:
n的值莫名其妙变化:越界写入覆盖了n的内存- 总线错误:访问了操作系统不允许程序触碰的内存区域
- 读取过多值:内存越界后的未定义行为,程序执行流程完全不可预测
而你之前用的int arr[n];是C99标准引入的变长数组(VLA),它会在运行时根据n的实际值分配对应的栈空间,数组有足够的存储空间容纳输入元素,自然不会出现越界问题,所以运行正常。
修复方案
方案一:使用变长数组(推荐,简单直接)
把数组声明移到scanf读取n之后,确保数组大小已知:
#include <stdio.h> void read_array(int arr[], int *n); void print_array(int arr[], int *n); int main() { int n; printf("Enter array length "); scanf("%d", &n); printf("\nmain elements %d", n); // 变长数组:在n确定后声明数组 int arr[n]; read_array(arr, &n); printf("\nElements main %d", n); print_array(arr, &n); return 0; } void read_array(int arr[], int *n) { int i; printf("\n Elements R_A %d", *n); printf("\nEnter elements"); for (i = 0; i < *n; i++) scanf("%d", &arr[i]); } void print_array(int arr[], int *n) { int i; printf("\n"); for (i = 0; i < *n; i++) printf("%d ", arr[i]); printf("\n Elements P_A %d", *n); }
方案二:动态内存分配(适合n较大的场景)
如果编译器不支持变长数组,或者n的值可能很大(栈空间有限,大数组容易栈溢出),可以用malloc动态分配内存:
#include <stdio.h> #include <stdlib.h> // 引入malloc/free的头文件 void read_array(int arr[], int *n); void print_array(int arr[], int *n); int main() { int n; int *arr = NULL; printf("Enter array length "); scanf("%d", &n); printf("\nmain elements %d", n); // 动态分配内存 arr = (int*)malloc(n * sizeof(int)); if (arr == NULL) { // 检查内存分配是否成功 printf("Memory allocation failed!\n"); return 1; } read_array(arr, &n); printf("\nElements main %d", n); print_array(arr, &n); // 释放动态分配的内存,避免内存泄漏 free(arr); arr = NULL; return 0; } void read_array(int arr[], int *n) { int i; printf("\n Elements R_A %d", *n); printf("\nEnter elements"); for (i = 0; i < *n; i++) scanf("%d", &arr[i]); } void print_array(int arr[], int *n) { int i; printf("\n"); for (i = 0; i < *n; i++) printf("%d ", arr[i]); printf("\n Elements P_A %d", *n); }
内容的提问来源于stack exchange,提问作者Siddhant Gore
相关产品推荐
相关产品推荐

