realloc扩容失败求助:向素数数组添加元素时内存分配出错
分析realloc调用失败及代码中的关键问题
核心错误原因
1. 初始内存分配大小错误
main函数里int *primes = (int *)(malloc(1));只分配了1字节,但int类型在大多数系统中占4字节,这直接导致*primes = 2;操作越界写入,破坏堆内存结构,后续的realloc调用会因为堆损坏而失败,返回NULL。
2. 指针传值调用导致修改无法同步
makePrimes函数的第一个参数int *primes是值传递,函数内部对primes的修改(比如primes = realloc(...))只会改变函数内的局部指针,不会影响main函数中的primes指针。就算realloc成功,main里的指针还是指向原来的小内存块;如果realloc返回NULL,原来的内存地址会被覆盖,直接造成内存泄漏。
3. 找到素数后未完成赋值操作
在makePrimes中,找到素数后只执行了*(primes + (*primesLength - 1));,这行代码只是读取数组最后一个位置的值,并没有把找到的lastValue存入数组,等于白扩容了。
4. isPrime函数逻辑冗余(非直接崩溃原因,但影响效率)
isPrime里的循环for (int iii = 0; iii < (input - 2); iii++)完全没必要,只需要循环到sqrt(input)即可,当前写法会导致大数的素数判断效率极低。
修正后的代码
#include <stdio.h> #include <stdlib.h> #include <math.h> // 要修改main中的指针,需传递指针的指针 void makePrimes(int **primes, int *primesLength, int primeTarget); int isPrime(int input); int main(void) { // 初始分配1个int的大小,而非1字节 int *primes = malloc(sizeof(int)); if (primes == NULL) { perror("malloc failed"); return 1; } *primes = 2; int primesLength = 1; // 传递指针的地址 makePrimes(&primes, &primesLength, 3); // 先判断长度,避免越界访问 if (primesLength >= 3) { printf("%d\n", primes[2]); } else { printf("数组长度不足\n"); } free(primes); return 0; } //* 找到目标序号的素数(2是第0个素数) //! 注意:primeTarget从0开始计数,primesLength从1开始计数 void makePrimes(int **primes, int *primesLength, int primeTarget) { if (*primesLength >= primeTarget + 1) return; int lastValue = (*primes)[*primesLength - 1]; while (*primesLength != primeTarget + 1) { lastValue++; if (isPrime(lastValue)) { (*primesLength)++; // 用临时变量接收realloc结果,避免失败时丢失原内存 int *temp = realloc(*primes, *primesLength * sizeof(int)); if (temp == NULL) { perror("realloc failed"); // 错误回滚长度 (*primesLength)--; return; } *primes = temp; // 将找到的素数存入数组末尾 (*primes)[*primesLength - 1] = lastValue; } } } //* 判断一个整数是否为素数 int isPrime(int input) { if (input <= 1) return 0; if (input == 2) return 1; // 偶数直接排除 if (input % 2 == 0) return 0; // 只检查到平方根,且只遍历奇数 for (int testFactor = 3; testFactor <= sqrt(input); testFactor += 2) { if (input % testFactor == 0) return 0; } return 1; }
修正要点说明
- 初始malloc改为
malloc(sizeof(int)),分配正确的内存大小。 makePrimes的第一个参数改为int **primes(指针的指针),确保函数能修改main中的指针变量。- 使用临时变量接收
realloc返回值,避免realloc失败时丢失原内存地址。 - 找到素数后,将
lastValue赋值给数组的新位置。 - 优化
isPrime函数,减少不必要的循环,提升效率。 - 添加内存分配失败的错误处理,增强代码健壮性。
内容的提问来源于stack exchange,提问作者Jman4546
相关产品推荐
相关产品推荐

