C语言数组插入操作出现垃圾值,请求技术协助
C语言数组插入功能垃圾值问题排查与修复
我不太熟悉C语言,目前正在开发一个支持用户选择操作的数组项目,已完成插入功能,但运行代码时插入元素后会出现垃圾值。
问题代码
#include<stdio.h> #include<stdlib.h> int main(){ int n, opt, i, insOpt, pos, newEle; printf("Enter the number of elements you want to store in the array: "); scanf("%d", &n); int* arr = (int*) malloc(n*sizeof(int)); printf("Enter all %d elements you want to store in the array: ", n); for(i=0; i<n; i++){ scanf("%d", &arr[i]); } options: printf("Enter the operation you want to perform: \n 1. Insertion \n 2. Deletion \n 3. Traversing \n 4. Searching \n 5. Sorting \n 6.Reverse of array \n"); scanf("%d", &opt); switch (opt) { case 1: n++; int* newArr=(int*) realloc(arr, n*sizeof(int)); for(i=0; i<n-1; i++){ newArr[i] = arr[i]; } free(arr); arr = newArr; printf("Pick where you want to insert: \n 1. Beginning \n 2. Middle \n 3. End \n 4. Position\n"); scanf("%d", &insOpt); switch (insOpt) { case 1: pos=0; break; case 2: // break; case 3: pos=n; break; case 4: printf("Enter the position: "); scanf("%d", &pos); break; default: printf("Please pick between 1 to 4: "); break; } printf("Enter the element: "); scanf("%d", &newEle); for(i=n-1; i>=pos-1; i--){ arr[i]=arr[i-1]; } arr[pos-1] = newEle; printf("Array after insertion: "); for(i=0; i<n; i++){ printf("%d ",arr[i]); } break; default: break; } } return 0; }
错误示例
Array after insertion: 8 1512474568 5 1571285629 1432712575 3
问题根源
索引越界读取垃圾值
当选择开头插入时,pos被设为0,后续移动元素的循环条件i >= pos-1会让i从新数组最后一个索引(n-1)递减到-1。当i=0时,arr[i-1]即arr[-1],属于数组越界访问,会读取内存中的随机垃圾值并赋值到数组中,导致输出异常。插入位置逻辑错误
- 末尾插入时,
pos被设为n,pos-1等于n-1(新数组最后一个索引),此时执行循环会无意义地覆盖最后一个元素。 - 手动复制数组操作冗余:
realloc扩容成功时会自动保留原数组数据,无需手动循环复制;且复制后free(arr)存在风险——若realloc返回新地址,原arr已被系统回收,此操作属于多余且可能引发问题。
- 末尾插入时,
缺少合法性检查
未对用户输入的位置做边界校验,若输入非法位置会直接引发越界。
修复后的代码
#include<stdio.h> #include<stdlib.h> int main(){ int n, opt, i, insOpt, pos, newEle; printf("Enter the number of elements you want to store in the array: "); scanf("%d", &n); int* arr = (int*) malloc(n*sizeof(int)); if(arr == NULL){ // 增加内存分配失败判断 printf("Memory allocation failed!\n"); return 1; } printf("Enter all %d elements you want to store in the array: ", n); for(i=0; i<n; i++){ scanf("%d", &arr[i]); } options: printf("Enter the operation you want to perform: \n 1. Insertion \n 2. Deletion \n 3. Traversing \n 4. Searching \n 5. Sorting \n 6.Reverse of array \n"); scanf("%d", &opt); switch (opt) { case 1: // 先扩容,成功后再更新数组长度 int* newArr=(int*) realloc(arr, (n+1)*sizeof(int)); if(newArr == NULL){ printf("Memory reallocation failed!\n"); free(arr); return 1; } arr = newArr; n++; printf("Pick where you want to insert: \n 1. Beginning \n 2. Middle \n 3. End \n 4. Position\n"); scanf("%d", &insOpt); switch (insOpt) { case 1: pos = 0; // 0代表数组第一个位置(0-based索引) break; case 2: pos = n/2; // 补全中间位置逻辑 break; case 3: pos = n-1; // 末尾位置为新数组最后一个索引 break; case 4: printf("Enter the position (1-based): "); scanf("%d", &pos); pos--; // 转换为0-based索引 // 校验位置合法性 if(pos <0 || pos >=n){ printf("Invalid position!\n"); free(arr); return 1; } break; default: printf("Please pick between 1 to 4!\n"); free(arr); return 1; } printf("Enter the element: "); scanf("%d", &newEle); // 仅当插入位置不是末尾时,才需要移动元素 if(pos != n-1){ // 从最后一个元素开始,向后移动到pos位置 for(i = n-1; i > pos; i--){ arr[i] = arr[i-1]; } } arr[pos] = newEle; // 直接在目标索引插入元素 printf("Array after insertion: "); for(i=0; i<n; i++){ printf("%d ",arr[i]); } break; default: printf("Invalid operation!\n"); break; } free(arr); // 释放内存,避免泄漏 return 0; }
关键修复点
- 修正索引逻辑:统一使用0-based索引,移动元素的循环改为
i > pos,仅移动pos到n-2的元素,避免越界。 - 优化内存操作:先执行
realloc并检查结果,成功后再更新数组长度和指针;移除冗余的手动复制操作。 - 补全逻辑与校验:补全中间位置插入逻辑,对用户输入的位置做合法性校验,末尾插入时直接赋值无需移动元素。
内容的提问来源于stack exchange,提问作者Dev
相关产品推荐
相关产品推荐

