我正在编写一个程序,以查找所有小于一定数的素数。一旦我的素数列表超过255000个素数,我就会收到错误“细分错误:11”。活动监视器说我的进程仅使用1.2MB。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include <unistd.h>
int main(){
int N;
int arraySize = 1;
int *primes = malloc(100*sizeof(int));
int isPrime = 1;
primes[0] = 2;
int timesRealloc = 0;
int availableSlots = 100;
printf("Please enter the largest number you want checked: \n");
scanf("%d", &N);
int j = 0;
int i;
for (i = 3; i <= N; i++){
j = 0;
isPrime = 1;
while (primes[j] <= sqrt(i)) {
if (i%primes[j] == 0) {
isPrime = 0;
break;
}
j++;
}
if (isPrime == 1){
primes[arraySize] = i;
arraySize++;
availableSlots = availableSlots - 1;
}
if (availableSlots == 0){
timesRealloc++;
availableSlots = 100;
primes = realloc(primes, 100*sizeof(int));
}
}
/*
for (i = 0; i < arraySize; i++){
printf("%d\n", primes[i]);
}
*/
printf("process ID is %d\n", getpid());
printf("I found %d primes\n", arraySize);
printf("Memory was reallocated %d times\n", timesRealloc);
printf("The largest prime I found was %d\n", primes[(arraySize-1)]);
return 0;
}
答案 0 :(得分:3)
如前所述,您离开数组素数
这里的代码经过最少的修改即可正常运行:
#include <math.h>
#include <sys/types.h>
#include <unistd.h>
int main(){
int N;
int arraySize = 1;
int *primes = malloc(100*sizeof(int));
int isPrime = 1;
primes[0] = 2;
int timesRealloc = 0;
int availableSlots = 100;
printf("Please enter the largest number you want checked: \n");
scanf("%d", &N);
int j = 0;
int i;
for (i = 3; i <= N; i++){
j = 0;
isPrime = 1;
while (primes[j] <= sqrt(i)) {
if (i%primes[j] == 0) {
isPrime = 0;
break;
}
j++;
}
if (isPrime == 1){
primes[arraySize] = i;
arraySize++;
/* LINE REMOVED */
}
if (arraySize == availableSlots){ /* MODIFIED */
timesRealloc++;
availableSlots += 100; /* MODIFIED */
primes = realloc(primes, availableSlots*sizeof(int)); /* MODIFIED */
}
}
/*
for (i = 0; i < arraySize; i++){
printf("%d\n", primes[i]);
}
*/
printf("process ID is %d\n", getpid());
printf("I found %d primes\n", arraySize);
printf("Memory was reallocated %d times\n", timesRealloc);
printf("The largest prime I found was %d\n", primes[(arraySize-1)]);
return 0;
}
更改通过注释指示
对我来说, arraySize 必须重命名为 numberOfPrimes ,而 availableSlots 必须重命名 arraySize
编译和执行:
pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra p.c -lm
pi@raspberrypi:/tmp $ ./a.out
Please enter the largest number you want checked:
500000
process ID is 6337
I found 41538 primes
Memory was reallocated 415 times
The largest prime I found was 499979
在 valgrind 下执行:
pi@raspberrypi:/tmp $ valgrind ./a.out
==6354== Memcheck, a memory error detector
==6354== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6354== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==6354== Command: ./a.out
==6354==
1000
Please enter the largest number you want checked:
process ID is 6354
I found 168 primes
Memory was reallocated 1 times
The largest prime I found was 997
==6354==
==6354== HEAP SUMMARY:
==6354== in use at exit: 800 bytes in 1 blocks
==6354== total heap usage: 4 allocs, 3 frees, 3,248 bytes allocated
==6354==
==6354== LEAK SUMMARY:
==6354== definitely lost: 800 bytes in 1 blocks
==6354== indirectly lost: 0 bytes in 0 blocks
==6354== possibly lost: 0 bytes in 0 blocks
==6354== still reachable: 0 bytes in 0 blocks
==6354== suppressed: 0 bytes in 0 blocks
==6354== Rerun with --leak-check=full to see details of leaked memory
==6354==
==6354== For counts of detected and suppressed errors, rerun with: -v
==6354== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
素数必须在最后释放,以免发生内存泄漏
仅是一个细节,但输入1时行为不是预期的
pi@raspberrypi:/tmp $ ./a.out
Please enter the largest number you want checked:
1
process ID is 6388
I found 1 primes
Memory was reallocated 0 times
The largest prime I found was 2
2大于1;-)
这是因为您强制存在2(primes[0] = 2;
等)
答案 1 :(得分:0)
这里有两个主要问题。
首先,您没有按照自己的想象分配足够的空间。您在此处进行初始分配:
int *primes = malloc(100*sizeof(int));
然后在此处重新分配:
primes = realloc(primes, 100*sizeof(int));
您要重新分配的空间量与原始大小相同。您并没有使数组更大。您可以通过跟踪当前容量并根据需要增加容量来解决此问题。因此初始分配如下所示:
int capacity = 100;
int *primes = malloc(capacity*sizeof(int));
重新分配如下:
timesRealloc++;
availableSlots = 100;
capacity += availableSlots;
primes = realloc(primes, capacity*sizeof(int));
第二个问题是,您将arraySize
从1开始写入primes[arraySize]
,但是availableSlots
的初始值是100。因此,当您达到当前容量时,您实际上是在写入最后一个元素。
将availableSlots
初始化为99,而不是10:
int availableSlots = 99;
此外,请不要忘记最后free(primes)
,以免造成内存泄漏。