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.
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
.
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;
}
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';
}
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