Sieve of Eratosthenes implementation - c++

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.

Related

C++ Memory leak error when resizing C++ dynamic array

The code below converts lets say array 3,9,3 to sorted array of integers 3,3,3,3,3 by converting 9 into sum of maximum possible parts.
The link to code/algorithm used in this code is answered at
https://stackoverflow.com/a/75331557/21145472
I am struck in this C++ code. When I ran it yesterday it was fine but today it gives memory leak error when function resizeArray() is run third time.
Please help fix this memory leak
#include<cmath>
#include <algorithm>
#include <iterator>
using namespace std;
void resizeArray(int *orig, int size, int newSize) {
int *resized = new int[newSize];
for (int i = 0; i < size; i ++)
resized[i] = orig[i];
delete [] orig;
orig = resized;
}
int main(){
int n = 3;
int *arr = new int[n];
int arrLength = n;
arr[0] = 3;
arr[1] = 9;
arr[2] = 3;
int *arrSorted = new int[0];
int sortedArrayLength = 0;
int temp;
unsigned long long int limit = 10e4;
long long parts = 0;
int extra = 0;
int mainArrayIndex = 0;
for(int i = 0; i<n/2; i++){
temp = arr[i];
arr[i] = arr[n-i-1];
arr[n-i-1] = temp;
}
for(int i = 0; i < n; i++){
parts = floor((arr[i] - 1) / (limit)) + 1;
limit = arr[i] / parts;
extra = arr[i] % parts;
for(int index = 0; index < extra; index++){
resizeArray(arrSorted, sortedArrayLength, sortedArrayLength + 1);
arrSorted[mainArrayIndex] = limit+1;
mainArrayIndex+=1;
sortedArrayLength+=1;
}
for(int index = 0; index < parts - extra; index++){
resizeArray(arrSorted, sortedArrayLength, sortedArrayLength + 1);
arrSorted[mainArrayIndex] = limit;
mainArrayIndex+=1;
sortedArrayLength+=1;
}
}
cout << "Array sorted steps taken" << " " << sortedArrayLength - arrLength;
cout << endl;
for(int i = 0; i < sortedArrayLength; i++){
if(i == 0)
cout << "[";
cout << arrSorted[i];
if(i < sortedArrayLength - 1)
cout << ", ";
if(i == sortedArrayLength - 1)
cout << "]";
}
delete []arr;
delete []arrSorted;
}
Your helper function's orig = resized; doesn't reassign your main function's arrSorted as you intend. Use a reference:
void resizeArray(int *&orig, ...) {
(That and the lack of including iostream are the only correctness issues I see, and this fix got rid of the error.)

Can't understand reason of the SIGTRAP in c++ code

I am writing some function for work with matrix.
I received correct output:
__11111111
__11111111
__333333333
__444444444444
But then program didn't stop and return invalid code
Process finished with exit code -1073741819 (0xC0000005)
How can i fix the error?
I tried debugger (gdb) and found out this:
Signal = SIGTRAP
And debugger presented me file new_allocator.h (attempt to deallocate nullptr)
// __p is not permitted to be a null pointer.
void
deallocate(pointer __p, size_type)
{ ::operator delete(__p); }
My code
#include <bits/stdc++.h>
using namespace std;
#define EPS 0.000001
int dualMatrix(vector<vector<double>> a) {
int n = a.size();
int m = a[0].size();
for (int col=0, row=0; col<m && row<n; ++col) {
int sel = row;
for (int i=row; i<n; ++i)
if (abs (a[i][col]) > abs(a[sel][col]))
sel = i;
if (abs(a[sel][col]) < EPS)
continue;
for (int i=col; i<=m; ++i)
swap(a[sel][i], a[row][i]);
cout << "__11111111\n";
for (int i=0; i<n; ++i)
if (i != row) {
if (a[row][col] == 0) {
cout << "DIVIDER IS ZERO" << endl;
return -1;
}
double c = a[i][col] / a[row][col];
for (int j=col; j<=m; ++j)
a[i][j] -= a[row][j] * c;
}
++row;
}
int rank = 0;
for (int i = 0; i < n; ++i) {
double temp = a[i][i];
if (temp == 0) {
cout << "Diagonal element is 0 at the row=" << i << endl;
rank = i;
break;
}
for (int j = 0; j < m; ++j) {
a[i][j] /= temp;
}
}
cout << "__333333333\n";
//printMatrix(a);
cout << "__444444444444\n";
return 0;
}
int main() {
vector<vector<double>> tmp {{1, 2, 3}, {3, 4, 5}};
dualMatrix(tmp);
cout << "__END" << endl;
return 0;
}
int m = a[0].size();
The size of the vector is m
for (int i=col; i<=m; ++i)
swap(a[sel][i], a[row][i]);
Here, i is outside the bounds of the vectorsa[sel] and a[row]. Accessing the vector outside of its bounds with the subscript operator has undefined behaviour.
Same here:
for (int j=col; j<=m; ++j)
a[i][j] -= a[row][j] * c;
How can i fix the error?
Don't access the vector outside of its bounds. If the size of the vector is 3, then the valid indices are 0, 1 and 2. If the size if m, then valid indices are 0, ..., m - 1

Heap corruption detected error in C++

Here is my code:
#include<iostream>
#include<cstdlib>
using namespace std;
int main() {
int** arr=NULL;
int num=0;
cin >> num;
int* big=NULL;
arr = new int*[num];
for (int i = 0; i < num; i++) {
arr[i] = new int[5];
}
big = new int[num];
for (int i = 0; i < num; i++) {
for (int j = 0; j < 5; j++) {
while (1) {
cin >> arr[i][j];
if (arr[i][j] >= 0 && arr[i][j] < 100)
break;
}
}
}
for (int i = 0; i < 5; i++) {
big[i] = 0;
}
for (int i = 0; i < num; i++) {
for (int j = 0; j < 5; j++) {
if (big[i] < arr[i][j]) {
big[i] = arr[i][j];
}
}
}
for (int i = 0; i < num; i++) {
cout << "Case #" << i + 1 << ": " << big[i] << endl;
}
delete[]big;
for (int i = num-1; i>=0; i--) {
delete[]arr[i];
}
delete[]arr;
return 0;
}
When I run this code, it says that there are heap corruption error (heap corruption detected). I think it means that there are some errors at 'new' or 'delete' parts in my codes, but I cannot find them. I hope someone to answer. Thanks.
Error is here:
big = new int[num];
...
for (int i = 0; i < 5; i++) {
big[i] = 0;
}
So when you have num less than 5 you are writing outside the array.
Anyway you are using C++ so use vector for such tasks.
#include<iostream>
#include<cstdlib>
#include<vector>
using namespace std;
int main() {
vector<vector<int>> arr;
int num=0;
cin >> num;
arr.resize(num, vector<int>(5));
for (auto &row : arr) {
for (auto &cell : row) {
while (1) {
cin >> cell ;
if (cell >= 0 && cell < 100)
break;
}
}
}
vector<int> big(arr.size());
for (int i = 0; i < arr.size(); i++) {
for (auto &cell : arr[i]) {
if (big[i] < cell) {
big[i] = cell;
}
}
}
for (int i = 0; i < num; i++) {
cout << "Case #" << i + 1 << ": " << big[i] << endl;
}
return 0;
}
In many places in your code, you're indexing your big array using indexes from 0 to 5, while the array is allocated using user input, if user input was 4 for example, your code is undefined behavior.
If you're using c++, you shouldn't be manually allocating the arrays, use std::vector instead, it will take care of managing memory for you, so you don't have to new and delete memory yourself.
With std::vector, your code would look somewhat like this.
std::vector<std::vector<int>> arr;
std::vector<int> big;
cin>>num;
arr.resize(num, std::vector<int>(5));
big.resize(5);
You will also be able to use at method to access elements while bound-checking, and size method to get the number of elements of the array.

Finalize the magic square generator

This code that runs only for odd N. The problem is that there are no ideas how to add support for even values N
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
setlocale(0, "");
int n;
cout << "Enter the size of the magic square - ";
cin >> n;
int **matrix = new int *[n];
for (int i = 0; i < n; ++i)
{
matrix[i] = new int[n];
}
int nsqr = n * n;
int i = 0, j = n / 2;
for (int k = 1; k <= nsqr; ++k)
{
matrix[i][j] = k;
i--;
j++;
if (k % n == 0)
{
i += 2;
--j;
}
else
{
if (j == n)
{
j -= n;
}
else if (i < 0)
{
i += n;
}
}
}
cout << "\n\nMagic square size - " << n << "\n\n";
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout << matrix[i][j] << "\t";
}
cout << endl;
}
for (i = 0; i < n; i++)
delete[] matrix[i];
delete[] matrix;
system("pause >> null");
return 0;
}
I would be grateful for tips on troubleshooting.
If i'm not mistaken, the problem is in this line:
int i = 0, j = n / 2;
But i don't know how to change the code to support even values
I would assume that you meant normal magic square (where the number are restricted to 1,2..n^2)
First of all, it's impposible to construct such magic square for n=2.
2nd, you would need an whole new algorithm for it, which is much more complicated. The problem (constructing magic square for any even number) is solved in this paper and while there isn't any psaudo code there, the implementation from the explenation is quite straightforward (long one though).
the problem is here:
i = 0;
int j = n / 2;
for (int k = 1; k <= nsqr; ++k)
{
matrix[i][j] = k;
i--;
}
look how you decrement i inside the loop and making it as an index of the array so:
matrix[-3][j] = k; // will be in your code
you are messing deliberately with the indexes of the array
I found answer on my question in this artcile
I made full revision my algorithm based on this article. Later posted listing the resulting program

C++ for loop array assignment. Getting junk returned

I'm trying to generate LIMIT (lets say limit = 1000) prime numbers and store them to an array, but I get junk returned. Here's my code:
#include <iostream>
using namespace std;
void prime_num(int);
int main()
{
int primes[1000];
int n, p, t, LIMIT = 1000;
for(n=2; n <= LIMIT; n++)
{
t=0;
for(p=2; p <= n/2; p++)
{
if (n%p == 0)
{
t = 1;
break;
}
}
if(!t)
primes[p-2] = n;
}
for (int i = 0; i < LIMIT; i++)
cout << primes[i] <<" ";
return 0;
}
Define a variable outside the outer loop:
int count=0;
and then use it here:
primes[count++] = n;
then print as:
for (int i = 0; i < count; i++)
cout << primes[i] <<" ";
Explanation:
You're not generating 1000 prime numbers, rather you're generating all prime numbers less than or equal to 1000.
As #Jerry Coffin commented, your code should be like this:
Note : I'm not talking about correctness, rather the skeleton of the program; so you decide if is_prime() function is correct or not, optimized or not, etc.
bool is_prime(int n)
{
for(int p=2; p <= n/2; p++)
{
if (n%p == 0)
{
return false;
}
}
return true;
}
int main()
{
int primes[1000];
int n, p, t, LIMIT = 1000;
int count=0;
for(n=2; n <= LIMIT; n++)
{
if (is_prime(n) )
primes[count++] = n;
}
for (int i = 0; i < count; i++)
cout << primes[i] <<" ";
return 0;
}
Correctness and Optimization of is_prime():
Now you decide the correctness of is_prime(). Is it correctly written? Is it optimized? Do you really need to check for all integers in the range [2,n/2]?