C语言动态可扩展数组输入超8个出现垃圾值的原因及修复方案
问题:动态扩展数组输入超过8个值时出现垃圾值
我尝试用以下C语言代码实现动态扩展数组,让用户输入数值(输入-1结束)。但当输入的数值数量超过8个时,输出结果中会出现垃圾值。
原代码
#include<stdio.h> #include<stdlib.h> int main(){ int *number=(int *)malloc(sizeof(int)),i=0,*new_ptr; printf("Enter a number to store it or -1 to finish the storage\n"); scanf("%d",number); while(*(number+i)!=-1){ printf("Enter a number to store it or -1 to finish the storage:\n"); number=(int *)realloc(number,sizeof(number)+sizeof(int)); i++; scanf("%d",number+i); }; for(int j=0;j<i;j++){ printf("%d ",number[j]); }; return 0; }
运行输出
Enter a number to store it or -1 to finish the storage 1 Enter a number to store it or -1 to finish the storage: 2 Enter a number to store it or -1 to finish the storage: 3 Enter a number to store it or -1 to finish the storage: 4 Enter a number to store it or -1 to finish the storage: 5 Enter a number to store it or -1 to finish the storage: 6 Enter a number to store it or -1 to finish the storage: 7 Enter a number to store it or -1 to finish the storage: 8 Enter a number to store it or -1 to finish the storage: 9 Enter a number to store it or -1 to finish the storage: 0 Enter a number to store it or -1 to finish the storage: -1 1 2 3 4 5 6 7 8 540155953 540287027
问题原因
核心错误是误用sizeof(number)计算内存大小:
number是指针变量,sizeof(number)返回的是当前系统中指针类型的字节数(64位系统通常为8字节,32位为4字节),而非数组已分配的内存容量。- 原代码每次调用
realloc时,用sizeof(number)+sizeof(int)计算新内存大小,这意味着每次扩容后总内存大小固定(比如64位下是8+4=12字节,仅能容纳3个int元素)。当输入元素数量超过这个固定容量后,后续写入会越界访问未分配的内存,从而产生垃圾值。
另外还有两个次要问题:
- 未检查
malloc和realloc的返回值,若内存分配失败会导致程序崩溃。 - 直接将
realloc的返回值赋值给原指针,若realloc失败返回NULL,会丢失原内存地址造成内存泄漏。
修复方法
需要手动跟踪数组的已用元素数和总容量,按正确逻辑扩容:
- 初始化时设定初始容量(比如4个元素),同时记录已用元素数
count和总容量capacity。 - 当已用元素数达到总容量时,将容量翻倍(或按固定增量扩容),确保有足够内存存储新元素。
- 用临时指针接收
realloc的返回值,检查分配是否成功,避免内存泄漏。 - 调整循环逻辑,确保输入的-1不会被存入数组。
修复后的代码
#include<stdio.h> #include<stdlib.h> int main(){ int capacity = 4; // 初始容量 int count = 0; // 已存储的元素数量 int *number = (int *)malloc(capacity * sizeof(int)); int input; if (number == NULL) { printf("内存分配失败\n"); return 1; } printf("Enter a number to store it or -1 to finish the storage\n"); while (scanf("%d", &input) == 1 && input != -1) { // 检查是否需要扩容 if (count >= capacity) { capacity *= 2; // 容量翻倍 int *temp_ptr = (int *)realloc(number, capacity * sizeof(int)); if (temp_ptr == NULL) { printf("内存扩容失败\n"); free(number); return 1; } number = temp_ptr; } number[count++] = input; printf("Enter a number to store it or -1 to finish the storage:\n"); } // 输出结果 for (int j = 0; j < count; j++) { printf("%d ", number[j]); } free(number); // 释放内存 return 0; }
内容的提问来源于stack exchange,提问作者Newtron Malayalam
相关产品推荐
相关产品推荐

