C语言for循环操作动态数组时仅输出0、1就提前终止的问题
程序运行异常的原因定位
直接触发“仅输出0, 1就退出”的bug
你在第二个遍历循环中计算边界的写法存在原理性错误:
- 代码里的
primes是int*类型的指针,在64位系统下指针本身占8字节,sizeof(primes)拿到的是这个指针变量的尺寸,和它指向的堆内存总长度完全无关 - 计算边界时做的
sizeof(primes)/sizeof(int),在标准编译环境下等价于8 / 4 = 2,也就是说遍历循环的条件i < 2只会让循环跑2次,打印完0、1就直接跳出,根本不会触碰前面循环写入的其他元素。
这是你观察到输出仅停留在两个值的核心原因,和第一个循环跑了多少次无关,哪怕第一个循环正常跑完15000次,这段遍历代码也只会打印前两个数。
容易触发程序提前崩溃的隐患
你写的扩容循环虽然逐次计算申请大小的逻辑看似没有越界,但存在两处内存安全问题,极易触发段错误让程序直接终止:
- 没有校验
realloc的返回值:如果内存申请失败,realloc会返回NULL,你直接把返回值赋值给primes会永久丢失原有堆内存的地址,下一次循环对primes[i]的写入操作会直接触发非法内存访问,导致程序退出。 - 逐次扩容1个int大小的写法效率极低:每次realloc都会尝试重新申请连续内存、拷贝原有数据,频繁调用会大幅增加内存申请失败的概率,也会拖慢程序运行速度。
可正常运行的修正版本
#include<stdio.h> #include<stdlib.h> int main() { // 独立跟踪数组的实际元素数、当前内存可容纳的总容量 int elem_count = 0; int capacity = 1; int *primes = (int*)malloc(capacity * sizeof(int)); if (primes == NULL) { perror("初始内存申请失败"); return 1; } for (int i = 0; i < 15000; i++) { // 元素数占满当前容量时再触发扩容 if (elem_count == capacity) { int new_cap = capacity * 2; // 倍增扩容,减少realloc调用次数 int *temp = (int*)realloc(primes, new_cap * sizeof(int)); // 用临时变量接realloc返回值,避免失败时丢失原指针地址 if (temp == NULL) { perror("内存扩容失败"); free(primes); return 1; } primes = temp; capacity = new_cap; } primes[elem_count] = i; elem_count++; } // 遍历边界用实际存储的元素数计算 for (int i = 0; i < elem_count; i++) { printf("%i, ", primes[i]); } free(primes); return 0; }
内容的提问来源于stack exchange,提问作者user12248687
相关产品推荐
相关产品推荐

