简体   繁体   中英

Seg Fault When Initializing Array in C++ (Project Euler Number 3)

So I'm trying to write a program to solve the Project Euler problem on greatest prime factor, and while I know the code is structurally correct (insofar as it return correct answers for smaller numbers, including the example 13195 that they give), I keep receiving a segmentation fault when I input the number we are supposed to solve, which is 600851475143. The code is as follows:

#include <stdio.h>
#include <math.h>

main(){
    int number,a,b,c,i,j,n,gpf;
    printf("Input number to analyze: ");
    scanf("%d",&number);
    a = number/2;
    printf("%d\n",a);
    int* primesieve = new int[a+1];               /*IMPORTANT LINE*/
    for (i=0;i<a+1;i++){
        primesieve[i] = 1;
    }
    for (j=2;j<=a;j++){
        if (primesieve[j] == 1){
            for (c=2;j*c<=a;c++){
                primesieve[j*c] = 0;
            }
        }
    }
    for (n=2;n<=a;n++){
        b = number/n;
        printf("%d\n",b);
        if (number % n == 0){
            if (primesieve[b] == 1){
                gpf = b;
                n = a+1;
            }
        }
    }
    delete[] primesieve;
    printf("The greatest prime factor of %d is %d.\n",number,gpf);
}

The problem comes from the initialization of the array for the prime sieve, because I omitted all lines after that one and still encountered the problem. I originally declared the array using the following code, which returned a segmentation fault for values as low as 10 million.

int primesieve[a+1];

I searched for a solution on this site, which yielded the change to dynamic array allocation, but while this solved the problem for 10 million, it apparently did not for significantly larger values. Other solutions I noticed mentioned something about using malloc() or declaring the array statically outside of main(), but frankly I didn't understand those as my introductory programming class barely mentioned malloc() and I thought the code leading up to the declaration of the array needed to be contained in main(). (For reference: Segmentation Fault While Creating Large Arrays in C and Seg Fault when initializing array .) I'm sure this is a fairly simple problem, but I'm a relatively new programmer and thus have a poor understanding of allocating memory, so any suggestion, solution, or explanation of the other solutions I found would be greatly appreciated.

Overflow!

It can not allocate array size 600851475143 in your memory. In a 32-bit system it requires 4,476 GB .

600851475143 * sizeof(int64_t) = 4806811801144 = 4.4TB

In other words, this code will always crash unless you have 5TB of RAM.

You can make it a bit more bearable if you use bitmap for your sieve. For example, using 1 bit per number, and not mapping even numbers only needs 600851475143 / 8 / 2 = 35GB of RAM. Still a lot, but feasible if you have some money for the hardware.

Your experience is related to the physical limits and the precision of your compiler. The first attempt, allocating the array on the stack

int primesieve[a+1];

quickly failed, because on most systems the stack is rather limited in size compared to the heap.

Allocating on the heap

int* primesieve = new int[a+1]; 

gives you more space, but you still have the limit of addressable memory. Now, 600851475143 is quite a large number, even if you divide it by 2. And assuming the size of int is 4 bytes, you might wonder, if you really can address that much memory. With 32 bits you can address 2^32 = 4294967296 bytes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM