Sieve of Eratosthenes implementation

我们两清 提交于 2019-11-28 12:38:37

问题


I am trying to implement algorithm for Sieve of Eratosthenes but I don't know why this program crashes for larger programs. Initially I was using vector but now I am implementing this using dynamic memory allocation.

#include<iostream>
#include<cmath>
#include<cstdlib>
using namespace std;

unsigned isqrt(unsigned value) {
  return static_cast<unsigned>(sqrt(static_cast<float>(value)));
}

int main()
{
    int t;
    cin >> t;
    long long * N;
    long long * M;
    long long n, m;
    N = new long long[t];
    M = new long long[t];
    for(int i = 0; i < t ; i++){
        cin >> M[i] >> N[i];
    }

    for(int i = 0; i < t ; i++){
        n = N[i];
        m = M[i];

        bool * A;
        A = new bool[n];
        if(A == 0)
        {
            cout << "Memory cannot be allocated";
            return 0;
        }

        for(int i=0;i < n;i++){
            A[i]=true;
        }
        A[0] = false;
        A[1] = false;

        unsigned sqrt = isqrt(n);
        for(int i = 2; i <= sqrt; i++)
        {
            if(A[i] == true){
                for(int j = i*i; j <= n; j = j + i)
                {
                    A[j] = false;
                }
            }
        }

        for(int i = m;i < n;i++)
        {
            if(A[i] == true )
                cout << i << "\n";
        }

        delete[] A;
    }

    delete[] M;
    delete[] N;
    return 0;
}

The program crashes for larger values of n and m (~10^16). Kindly help me out.


回答1:


for(int j = i*i; j <= n; j = j + i)
                   ^^

If j == n then A[j] = false will assign to an element past the end of the array. The test should be j < n.




回答2:


If you're going to write a sieve of Eratosthenes in C++, how about if you actually use C++, not try to treat it as some demented cross between C and assembly language.

#include <vector>
#include <iostream>

unsigned long primes = 0;

int main() {
    int number = 10000000;
    std::vector<bool> sieve(number,false);
    sieve[0] = sieve[1] = true;

    for(int i = 2; i<number; i++) {
        if(!sieve[i]) {
            ++primes;
            for (int temp = 2*i; temp<number; temp += i)
                sieve[temp] = true;
        }
    }
    std::cout << "found: " << primes << " Primes\n";
    return 0;
}



回答3:


If n is big enough to cause memory allocation error program will crash due to incorrect memory allocation error handling here

 A = new bool[n];
        if(A == 0)
        {
            cout << "Memory cannot be allocated";
            return 0;
        }

new doesn't return 0 on error, but throws std::bad_alloc that doesn't get catched, which in turn will lead to unexpected() then terminate() and finally abort() to be called.
Correct version would be:

  try
  {
    A = new bool[n];
  }
  catch (std::bad_alloc& ba)
  {
    std::cerr << "Memory cannot be allocated: " << ba.what() << '\n';
  }



回答4:


Run this in a debugger to determine where the crash is and debug from there. It will most likely be apparent at that point.

You can do this either from an IDE or from command line. In the latter case compile with -g and run in a program such as gdb. Google something like "gdb cheatsheet" to get started.



来源:https://stackoverflow.com/questions/15980599/sieve-of-eratosthenes-implementation

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