C++ Array Allocation Segmentation Fault 11 Newbie

心不动则不痛 提交于 2019-12-10 11:45:04

问题


I am learning C++ from Algorithms in C++ by Robert Sedgewick. Right now I am working on the Sieve of Eratosthenes with a user specified upper bound on the largest prime. When I run the code with max 46349, it runs and prints out all primes up to 46349, however when I run the code with max 46350, a Segmentation fault occurs. Can someone help to explain why?

./sieve.exe 46349
 2 3 5 7 11 13 17 19 23 29 31 ...

./sieve.exe 46350
 Segmentation fault: 11

Code:

#include<iostream>

using namespace std;

static const int N = 1000;

int main(int argc, char *argv[]) {
    int i, M;

    //parse argument as integer
    if( argv[1] ) {
        M = atoi(argv[1]);
    }

    if( not M ) {
        M = N;
    }

    //allocate memory to the array
    int *a = new int[M];

    //are we out of memory?
    if( a == 0 ) {
        cout << "Out of memory" << endl;
        return 0;
    }

    // set every number to be prime
    for( i = 2; i < M; i++) {
        a[i] = 1;
    }

    for( i = 2; i < M; i++ ) {
        //if i is prime
        if( a[i] ) {
            //mark its multiples as non-prime
            for( int j = i; j * i < M; j++ ) {
                a[i * j] = 0;
            }
        }
    }

    for( i = 2; i < M; i++ ) {
        if( a[i] ) {
            cout << " " << i;
        }    
    }
    cout << endl;

    return 0;
}

回答1:


You have integer overflow here:

        for( int j = i; j * i < M; j++ ) {
            a[i * j] = 0;
        }

46349 * 46349 does not fit in an int.

On my machine, changing the type of j to long makes it possible to run the program for larger inputs:

    for( long j = i; j * i < M; j++ ) {

Depending on your compiler and architecture, you may have to use long long to get the same effect.




回答2:


When you run your program with a debugger, you will see that it fails at

a[i * j] = 0;

i * j overflows and becomes negative. This negative number is less than M, that's why it enters the loop once more and then fails on access to a[-2146737495].




回答3:


I see, the problem was declaring M as an int. When I declare i,M and j as long, this seems to work fine.




回答4:


In any reasonably modern C++, you will not get a null pointer back from new if the allocation fails unless you use a non-throwing new. That part of your code isn't going to work as you expect it to - you'll have to catch std::bad_alloc that might be emitted from the call to new instead.

You also want to declare your array indices as type size_t.



来源:https://stackoverflow.com/questions/15177018/c-array-allocation-segmentation-fault-11-newbie

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!