Memory error in finding prime sum - c++

Problem: Given an even number ( greater than 2 ), return two prime numbers whose sum will be equal to given number.
Solution: Using sieve of eratosthenes find all prime numbers upto given number. Then find the pair of numbers whose sum is equal to given number.
Code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
void primesum(int A)
{
std::vector<bool> primes(A + 1, 1);
std::vector<int> arr, final;
primes[0] = 0;
primes[1] = 0;
for (int i = 2; i <= int(sqrt(A)); i++)
{
if (primes[i] == 1)
{
for (int j = 2; i + j <= A; j++)
{
primes[i * j] = 0;
}
}
}
for (int i = 0; i < primes.size(); i++)
if (primes[i])
arr.push_back(i);
/* for (auto x : primes)
std::cout << x << " ";
std::cout << "\n"; */
std::vector<int>::iterator it;
for (int i = 0; i < arr.size(); i++)
{
it = std::find(arr.begin(), arr.end(), A - arr[i]);
if (it != arr.end())
{
final.push_back(arr[i]);
final.push_back(A - arr[i]);
break;
}
}
std::cout << final[0] << " " << final[1] << "\n";
return;
}
int main()
{
int x = 184;
primesum(x);
return 0;
}
This code is working for most of the cases except for case like when x=184. Error in this case is:
a.out: malloc.c:2394: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
[1] 13944 abort (core dumped) ./a.out
I'm not able to understand why this is happening and what's its solution?

Let x=184. Then primes.size() is 185. The first loop iterates till i=13. 13 is the prime number. The second loop iterates till j=171. In the loop you access primes[2223]. It is a write out of bounds, causes UB. As the result you get corrupted dynamic memory and the assertion.
It looks like you did a typo in the loop condition, you wanted i * j <= A.

With primes[i * j] = 0 you have invalid indices exceeding your vector size while finding the primes, that is the reason this code crashes. You can correct this to
for (int i = 2; i <= int(sqrt(A)); i++)
{
if (primes[i] == 1)
{
for (int j = 2; i * j <= A; j++)
{
primes[i * j] = 0;
}
}
}

Related

Debug Assertion Fail (vector subscript out of range)

I found that my result.push_back(make_pair(a[i], b[j]));, which
causing this error but i dont know why (i don't even access vector<pair<int,int>>result;)
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<utility>
using namespace std;
void input(int n,vector<int>&a) {
int temps;
for (int i = 0; i < n; i++) {
cin >> temps;
a.push_back(temps);
}
}
int main() {
//input
long n, m;
cin >> n; //6
vector<int>a, b;
input(n, a); //{2 5 4 1 7 5}
cin >> m; //7
input(m, b); //{2 3 1 3 2 4 6}
//algorithm
long max = *max_element(a.begin(), a.end()) + *max_element(b.begin(), b.end());
long min = *min_element(a.begin(), a.end()) + *min_element(b.begin(), b.end());
vector<pair<int, int>>result;
int possible = max, plate = 0;
for (int check = max; check >= min; check--) {
int j = 0, i = 0, plate2 = 0;
for (; i < a.size(); i++) {
if (a[i] >= check) {}
else {
if (j > b.size() - 1) { break; }
if (a[i] + b[j] >= check) {
j++; plate2++;
result.push_back(make_pair(a[i], b[j]));
}
else {
i--; j++;
}
}
}
if (i > a.size() - 1) { possible = check; plate = plate2; break; }
}
cout << possible << " " << plate << endl; //5 3
return 0;
}
if you remove the line result.push_back(make_pair(a[i],b[j]);, there is no error message anymore, so i think i'm not access wrong a[i] and b[j] elements
if (j > b.size() - 1) { break; } //(1)
if (a[i] + b[j] >= check) { //(2)
j++; plate2++; // HERE IS YOUR PROBLEM (3)
result.push_back(make_pair(a[i], b[j])); //(4)
Assume that j == b.size()-1 at the beginning. The if (j > b.size() - 1) clause is false, so the loop does not break. It continues with (2), which is okay. In (3) you add +1 to j, so now j == b.size(). In (4) you try to access b[j], which is now b[b.size()], which is invalid, as indizes start at 0.
IOW: You tried to assure that j never points beyond the number of valid elements, but then you increment j after that test and access invalid memory.

Why is this code giving me segmentation, ? when we print only count then it gives answer and when print ans[4] or any value then it gives error?

I am getting segmentation error , it gives output when only print ans[k] inside the function then it
gives corrct output but in main when I try to print ans[k] then it gives segmentation
i am new at progamming so i don't know more about it so please help me it's my assigment
question is
I have to create a array of factors of a number upto 4 * 10^6
Core Dump/Segmentation fault is a specific kind of error caused by accessing memory that “does not belong to you.”
When a piece of code tries to do read and write operation in a read only location in memory or freed block of memory, it is known as core dump.
It is an error indicating memory corruption.
#include <bits/stdc++.h>
using namespace std;
#define int long long int
vector<int> arr(1000001,0);
vector<int> ans;
bool isPrime(int n)
{
if (n <= 1)
return false;
if (n <= 3)
return true;
if (n % 2 == 0 || n % 3 == 0)
return false;
for (int i = 5; i * i <= n; i = i + 6)
if (n % i == 0 || n % (i + 2) == 0)
return false;
return true;
}
void factorpush()
{
for (int k = 5; k <= 4000001; k += 4)
{
if (isPrime(k))
{
arr[k] = 1;
}
}
arr.clear();
ans.clear();
for (int k = 5; k <= 4000001; k += 4)
{
if (arr[k] == 1)
{
int n = (k / 4);
ans[n] = (2 * n) - 1 + k;
}
else
{
vector<int> v;
for (int i = 1; i*i < k; i++)
{
if (k % i == 0)
{
if (k / i == i && i != k)
v.push_back(i);
else
{
if (i != k)
{
v.push_back(i);
}
if (k / i != k)
{
v.push_back(k/ i);
}
}
}
}
int count = k;
int count2 = 0;
for (auto x : v)
{
if (x != 1 && x!=k)
{
int n = (k/4);
count2 += ((2*n - 1)/x);
count += ((2*n - 1)/x)*x;
}
}
int n1 = (k/4);
int val = (2*n1) - 1 - count2;
count += val;
ans[n1] = count;
//cout<<ans[n1]<<"\n";
}
}
}
int32_t main()
{
factorpush();
int n;
cin>>n;
cout<<ans[n]<<"\n";`
return 0;
}
I didn't read your code well and there may be other errors, but at least the combination of
vector<int> arr(1000001,0);
and
for (int k = 5; k <= 4000001; k += 4)
{
if (isPrime(k))
{
arr[k] = 1;
}
}
is bad because arr[k] will go further than allocated.
You have to allocate enough elements like
vector<int> arr(4000002,0);
Also accessing arr[k] and ans[n] after arr.clear(); and ans.clear(); and without adding any elements is bad because the clear() function erases all elements from the vector. Also checking for arr[k] == 1 after the erasure doesn't make sense. Not understanding your code well, it looks like
arr.clear();
ans.clear();
should be replaced with something like
ans.clear();
ans.resize(1000001);

What does "not all control paths return a value" mean and how to troubleshoot. (C++)

I'm trying to create a function for an assignment that finds the two prime numbers that add up to the given sum. The instructions ask
"Write a C++ program to investigate the conjecture by listing all the even numbers from 4 to 100,000 along
with two primes which add to the same number.
Br sure you program the case where you find an even number that cannot be expressed as the sum of two
primes (even though this should not occur!). An appropriate message to display would be “Conjecture
fails!” You can test this code by seeing if all integers between 4 and 100,000 can be expressed as the sum
of two primes. There should be lots of failures."
I have created and tested the "showPrimePair" function before modifying it to integrate it into the main program, but now I run into this specific error
"C4715 'showPrimePair': not all control paths return a value"
I have already done my research to try to fix the error but it still
remains.
#include <iostream>
#include <stdio.h>
//#include <string> // new
//#include <vector> //new
//#include <algorithm>
using namespace std;
bool isPrime(int n);
//bool showPrimePair(int x);
//vector <int> primes; //new
const int MAX = 100000;
//// Sieve Sundaram function // new
//
//void sieveSundaram()
//{
// bool marked[MAX / 2 + 100] = { 0 };
// for (int i = 1; i <= (sqrt(MAX) - 1) / 2; i++)
// for (int j = (i * (i + 1)) << 1; j <= MAX / 2; j = j + 2 * i + 1)
// marked[j] = true;
//
// primes.push_back(2);
// for (int i = 1; i <= MAX / 2; i++)
// if (marked[i] == false)
// primes.push_back(2 * i + 1);
//}
// Function checks if number is prime //links to showPrimePair
bool isPrime(int n) {
bool prime = true;
for (int i = 2; i <= n / 2; i++)
{
if (n % i == 0) // condition for nonprime number
{
prime = false;
break;
}
}
return prime;
}
// Function for showing prime pairs ( in progress) Integer as a Sum of Two Prime Numbers
bool showPrimePair(int n) {
bool foundPair = true;
for (int i = 2; i <= n / 2; ++i)
// condition for i to be a prime number
{
if (isPrime(i) == 1)
{
// condition for n-i to be a prime number
if (isPrime(n - i) == 1)
{
// n = primeNumber1 + primeNumber2
printf("%d = %d + %d\n", n, i, n - i);
foundPair = true;
break;
}
}
}
if (foundPair == false) {
cout << " Conjecture fails!" << endl;
return 0;
}
}
// Main program in listing conjectures for all even numbers from 4-100,000 along q/ 2 primes that add up to same number.
int main()
{
//sieveSundaram();
cout << "Goldbach's Conjecture by Tony Pham " << endl;
for (int x = 2; x <= MAX; x++) {
/*if (isPrime(x) == true) { //works
cout << x << " is a prime number " << endl;
}
else {
cout << x << " is not a prime number " << endl;
}*/
showPrimePair(x);
}
cout << "Enter any character to quit: ";
cin.get();
}
First you can find all prime numbers in the desired range using the Sieve of Eratosthenes algorithm. Next, you can insert all found primes into a hash set. Finally for each number n in the range you can try all primes p that don't exceed n/2, and probe if the n-p is also a prime (as long as you have a hash set this operation is very fast).
Here is an implementation of Dmitry Kuzminov's answer. It takes a minute to run but it does finish within a reasonable time period. (Also, my implementation skips to the next number if a solution is found, but there are multiple solutions for each number. Finding every solution for each number simply takes WAAAAY too long.)
#include <iostream>
#include <vector>
#include <unordered_set>
std::unordered_set<long long> sieve(long long max) {
auto arr = new long long[max];
std::unordered_set<long long> ret;
for (long long i = 2; i < max; i++) {
for (long long j = i * i; j < max; j+=i) {
*(arr + (j - 1)) = 1;
}
}
for (long long i = 1; i < max; i++) {
if (*(arr + (i - 1)) == 0)
ret.emplace(i);
}
delete[] arr;
return ret;
}
bool is_prime(long long n) {
for(long long i = 2; i <= n / 2; ++i) {
if(n % i == 0) {
return false;
}
}
return true;
}
int main() {
auto primes = sieve(100000);
for (long long n = 4; n <= 100000; n+=2) {
bool found = false;
for (auto prime : primes) {
if (prime <= n / 2) {
if (is_prime(n - prime)) {
std::cout << prime << " + " << n - prime << " = " << n << std::endl;
found = true;
break; // Will move onto the next number after it finds a result
}
}
}
if (!found) { // Replace with whatever code you'd like.
std::terminate();
}
}
}
EDIT: Remember to use delete[] and clean up after ourselves.

Vector Subscript out of Range; Comparing Elements of Vectors

I am currently working on a program that finds prime numbers, I know there are less convoluted ways to find prime numbers but I'm trying to practice comparing elements in vectors (not_prime_numbers & number bank(numbers from 1-100)) and when a value that is a prime number is found it is put into the final prime_number vector.
I am using loops to compare elements inside the vectors. When I ask the program to display the vector not_prime_numbers this is not a problem, nor number bank, however when I ask it to display the prime_number vector I get the error vector subscript out of range. Why are the vector elements in prime numbers I am asking to display out of range however using the same loop method to display the elements of vectors not_prime_numbers & number_bank work. Is it a problem with how I compared the two vectors to put the element into a third vector (prime_numbers)?
#include "pch.h"
#include <iostream>
#include<vector>
int main()
{
float i = 1.0;
unsigned int n = 0;
std::vector<float>not_prime_numbers;
std::vector<float>number_bank;
std::vector<float>prime_numbers;
while (i <= 100.0)
{
for (float j = 1.0;j<(i);++j)
{
float p = i / j;
if (abs(floor(p)) == p&&j!=1.0)
{
not_prime_numbers.push_back(i);
break;
}
}
++i
}
for (float k = 1.0; k <= 100.0; ++k)
{
number_bank.push_back(k);
}
for (unsigned int m = 0; m <= number_bank.size(); ++m)
{
while (n <= not_prime_numbers.size())
{
if (not_prime_numbers[n] == number_bank[m])
{
break;
}
if (n == m)
{
prime_numbers.push_back(number_bank[m]);
}
if (not_prime_numbers[n] != number_bank[m])
{
++n;
}
}
}
std::cout << "All prime numbers between 0 and 100 are as follows:\n";
for (unsigned int j = 0; j <= prime_numbers.size(); ++j)
{
std::cout << prime_numbers[j] << "\n";
}
}
This is not homework, just personal practice. Any help would be greatly appreciated.
in
while (n <= not_prime_numbers.size())
{
if (not_prime_numbers[n] == number_bank[m])
you go after the last element, test must be n < not_prime_numbers.size()
and same error when you print the result :
for (unsigned int j = 0; j <= prime_numbers.size(); ++j)
{
std::cout << prime_numbers[j] << "\n";
}
must be
for (unsigned int j = 0; j < prime_numbers.size(); ++j)
{
std::cout << prime_numbers[j] << "\n";
}
If valgrind is available on your host, use it to find that kind of errors and lot more

Generate numbers from 2 to 10,000. The numbers printed can only be a multiple of 2 prime numbers

Homework: I'm just stumped as hell. I have algorithms set up, but I have no idea how to code this
Just to be clear you do not need arrays or to pass variables by reference.
The purpose of the project is to take a problem apart and using Top-Down_Design or scratch pad method develop the algorithm.
Problem:
Examine the numbers from 2 to 10000. Output the number if it is a Dual_Prime.
I will call a DualPrime a number that is the product of two primes. Ad where the two primes are not equal . So 9 is not a dual prime. 15 is ( 3 * 5 ) .
The output has 10 numbers on each line.
My Algorithm set-up
Step 1: find prime numbers.:
bool Prime_Number(int number)
{
for (int i = 2; i <= sqrt(number); i++)
{
if (number % 1 == 0)
return false;
}
return true;
}
Step 2: store prime numbers in a array
Step 3: Multiply each array to each other
void Multiply_Prime_Numbers(int Array[], int Size)
{
for (int j = 0; j < Size- 1; j++)
{
Dual_Prime[] = Arr[j] * Arr[j + 1]
}
}
Step 4: Bubble sort
void Bubble_Sort(int Array[], int Size) // Sends largest number to the right
{
for (int i = Size - 1; i > 0; i--)
for (int j = 0; j < i; j++)
if (Array[j] > Array[j + 1])
{
int Temp = Array[j + 1];
Array[j + 1] = Array[j];
Array[j] = Temp;
}
}
Step 5: Display New Array by rows of 10
void Print_Array(int Array[], int Size)
{
for (int i = 0; i < Size; i++)
{
cout << Dual_Prime[i] << (((j % 10) == 9) ? '\n' : '\t');
}
cout << endl;
}
I haven't learned dynamic arrays yet,
Although dynamic arrays and the sieve of Eratosthenes are more preferable, I tried to write minimally fixed version of your code.
First, we define following global variables which are used in your original implementation of Multiply_Prime_Numbers.
(Please check this post.)
constexpr int DP_Size_Max = 10000;
int DP_Size = 0;
int Dual_Prime[DP_Size_Max];
Next we fix Prime_Number as follows.
The condition number%1==0 in the original code is not appropriate:
bool Prime_Number(int number)
{
if(number<=1){
return false;
}
for (int i = 2; i*i <= number; i++)
{
if (number % i == 0)
return false;
}
return true;
}
In addition, Multiply_Prime_Numbers should be implemented by double for-loops as follows:
void Multiply_Prime_Numbers(int Array[], int Size)
{
for (int i = 0; i < Size; ++i)
{
for (int j = i+1; j < Size; ++j)
{
Dual_Prime[DP_Size] = Array[i]*Array[j];
if(Dual_Prime[DP_Size] >= DP_Size_Max){
return;
}
++DP_Size;
}
}
}
Then these functions work as follows.
Here's a DEMO of this minimally fixed version.
int main()
{
int prime_numbers[DP_Size_Max];
int size = 0;
for(int j=2; j<DP_Size_Max; ++j)
{
if(Prime_Number(j)){
prime_numbers[size]=j;
++size;
}
}
Multiply_Prime_Numbers(prime_numbers, size);
Bubble_Sort(Dual_Prime, DP_Size);
for(int i=0; i<DP_Size;++i){
std::cout << Dual_Prime[i] << (((i % 10) == 9) ? '\n' : '\t');;
}
std::cout << std::endl;
return 0;
}
The Sieve of Eratosthenes is a known algorithm which speeds up the search of all the primes up to a certain number.
The OP can use it to implement the first steps of their implementation, but they can also adapt it to avoid the sorting step.
Given the list of all primes (up to half the maximum number to examine):
Create an array of bool as big as the range of numbers to be examined.
Multiply each distinct couple of primes, using two nested loops.
If the product is less than 10000 (the maximum) set the corrisponding element of the array to true. Otherwise break out the inner loop.
Once finished, traverse the array and if the value is true, print the corresponding index.
Here there's a proof of concept (implemented without the OP's assignment restrictions).
// Ex10_TwoPrimes.cpp : This file contains the 'main' function. Program execution begins and ends there.
#include "pch.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void Homework_Header(string Title);
void Do_Exercise();
void Sieve_Of_Eratosthenes(int n);
void Generate_Semi_Prime();
bool Semi_Prime(int candidate);
bool prime[5000 + 1];
int main()
{
Do_Exercise();
cin.get();
return 0;
}
void Do_Exercise()
{
int n = 5000;
Sieve_Of_Eratosthenes(n);
cout << endl;
Generate_Semi_Prime();
}
void Sieve_Of_Eratosthenes(int n)
{
// Create a boolean array "prime[0..n]" and initialize
// all entries it as true. A value in prime[i] will
// finally be false if i is Not a prime, else true.
memset(prime, true, sizeof(prime));
for (int p = 2; p*p <= n; p++)
{
// If prime[p] is not changed, then it is a prime
if (prime[p] == true)
{
// Update all multiples of p
for (int i = p * p; i <= n; i += p)
prime[i] = false;
}
}
}
bool Semi_Prime(int candidate)
{
for (int index = 2; index <= candidate / 2; index++)
{
if (prime[index])
{
if (candidate % index == 0)
{
int q = candidate / index;
if (prime[q] && q != index)
return true;
}
}
}
return false;
}
void Generate_Semi_Prime()
{
for (int i = 2; i <= 10000; i++)
if (Semi_Prime(i)) cout << i << "\t";
}