Process returned -1073741819 (0xC0000005) (why though??) - c++

So i was solving my homework, and i did this piece of code which is supposed to find the biggest difference beetween two prime numbers in the interval of [a,b], and i got "Process returned -1073741819 (0xC0000005)"
#include <iostream>
#include <vector>
#include <bitset>
using namespace std;
bitset <10000000>v;
int main()
{
for (int i = 2; i < 10000000; i++)
{
if (v[i] == 0)
{
for (int j = i * i; j < 10000000; j += i)
v[j] = 1;
}
}
int n, a, b, maxi = 0, mini = 0, smax = 0;
cin >> a >> b;
int poz = a;
while (v[poz] == 1)
poz++;
int prev = poz;
poz++;
while (v[poz] == 1 && poz < b)
poz++;
if (poz == b && v[b] == 1)
{
cout << -1; return 0;
}
int next = poz;
poz++;
while (poz <= b)
{
if (next - prev > smax)
{
smax = next - prev;
maxi = next;
mini = prev;
}
if (v[poz] == 0)
{
prev = next;
next = poz;
}
poz++;
}
cout << mini << " " << maxi;
return 0;
}
i expected 43 with 47

In your initialisation loop when i is 46349, i*i is 2,148,229,801, this is larger than fits inside a signed 32-bit integer so evaluates to -2,146,737,495. v[j] then causes the crash.
You should either modify your code to use a larger data type or set the limit for i to sqrt(10000000) rather than 10000000.

I'm guessing that i*i overflows when i is large, leading to a negative value for j and an access violation on v[j]=1;.

You have a potential segmentation fault on line v[j]=1; where j may exceed 10000000.
Please check your boundaries.

Related

Why is my "vector subscript out of range"?

I am trying to make an algorithm that checks for duplicates. The algorithm takes in an integer p and aims to find the primitive root g if it satisfies that all values of g^x mod p (for values of x in the range of 0 to p - 2) are different.
I basically try to store all the values of g^x mod p in a vector and then I check for duplicates using a digitsTable vector that counts the frequency of each individual number. If the number is greater than 1, then it means there's a duplicate.
But the thing is, halfway through the algorithm, an error appears saying that the vector subscript is out of range. I did a bit of research and it refers to an accessing violation. I don't see where this is going wrong.
Here's the code:
#include <iostream>
#include <vector>
#define ll long long int
using namespace std;
ll gcd(ll a, ll b) {
ll r;
while (b != 0) {
r = a % b;
a = b;
b = r;
}
return a;
}
int main()
{
ll p;
cin >> p;
vector<ll> distinctIntegers;
vector<ll> digitsTable;
bool searching = true;
ll g = 2;
ll smallestRoot;
ll rootCount = 1;
while (searching) {
bool primeRoot = true;
distinctIntegers.push_back(1);
for (ll x = 1; x <= p - 2; ++x) {
distinctIntegers.push_back(g * distinctIntegers[x - 1] % p);
}
// fills a vector with zeroes
for (ll i = 0; i < distinctIntegers.size(); ++i) {
digitsTable.push_back(0);
}
// counts the frequency of each element in distinctIntegers.size()
for (ll i = 0; i < distinctIntegers.size(); ++i) {
++digitsTable[distinctIntegers[i]];
}
for (ll i = 0; i < distinctIntegers.size(); ++i) {
if (digitsTable[i] > 1) {
primeRoot = false;
++g;
break;
}
}
if (primeRoot) {
smallestRoot = g;
searching = false;
}
//test
distinctIntegers.clear();
digitsTable.clear();
}
for (int m = smallestRoot; m <= p - 1; ++m) {
if (gcd(m, p - 1) == 1) {
rootCount++;
}
}
cout << smallestRoot << " " << rootCount;
return 0;
// USED FOR TESTING
/*
* for (int i = 0; i < digitsTable.size(); ++i) {
cout << digitsTable[i] << " ";
}
cout << endl;
*/
}

Check whether all the pairs in an array are divisible by k

Given an array of integers and a number k, write a function that returns true if given array can be divided into pairs such that sum of every pair is divisible by k.
This code is producing correct results for all test cases except one I cannot find the glitch in it.
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
int k;
cin >> k;
int flag[n] = {0};
int p = 0;
int q = 0;
if (n % 2 != 0) {
cout << "False" << endl;
} else {
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if ((arr[i] + arr[j]) % k == 0 && flag[j] == 0) {
p = 1;
flag[j] = 1;
}
}
if (p == 0) {
q = 1;
cout << "False" << endl;
break;
}
}
if (q == 0) {
cout << "True" << endl;
}
}
}
return 0;
}
One of the big sources of bugs in code is messy code. So how do we clean up code? We modularize it. This means breaking up the code so that each portion of the code does one job well. Let's see what that looks like.
Function to check if something is divisible by k:
bool isDivisible(int number, int divisor) {
return number % divisor == 0;
}
Function to check all pairs:
The logic is as follows:
Take the first number in the list; call in n0.
For every remaining number n1, check if that plus the first number is divisible by k
When we find n1 such that n0 + n1 is divisible by k,
a. If the remaining numbers left over can also be split into divisible pairs, return true
b. Otherwise, continue searching
4.If we've searched through all the numbers, return false.
bool pairsDivisible(int* nums, int count, int k) {
if(count == 0) return true;
if(count % 2 != 0) return false; // count must be even
// 1.
int n0 = nums[0];
// 2.
for(int i = 1; i < count; i++) {
int n1 = nums[i];
// 3.
if(isDivisible(n0 + n1, k)) {
// Move the ith number so it's now nums[1]
std::swap(nums[1], nums[i]);
if(pairsDivisible(nums + 2, count - 2, k)) {
return true; // 3.a
} else {
// Reset the array
std::swap(nums[1], nums[i]);
}
}
}
return false;
}

the biggest common divisor of 2 numbers using arrays

How could I find the biggest common divisor of 2 numbers using array? I tried to solve it using 2 arrays and I couldn't finish it. How could I improve this program?
#include <iostream>
using namespace std;
int main()
{
unsigned int A[2][10], B[2][10], a, b, c_exp, d, i1, P, x;
bool apartine = false;
cout << "a="; cin >> a;
cout << "b="; cin >> b;
P = 1;
c_exp = 0;
i1 = 0;
while (a % 2 == 0)
{
c_exp++;
a = a/2;
}
if (c_exp != 0)
{
A[i1][0] = 2;
A[i1][1] = c_exp;
i1++;
}
d = 3;
while (a != 1 && d <= a)
{
c_exp=0;
while (a % d == 0)
{
c_exp++;
a = a/d;
}
if (c_exp!=0)
{
A[i1][0] = d;
A[i1][1] = c_exp;
i1++;
}
d = d+2;
}
cout << "\nMatricea A contine:";
for (int i = 0; i < i1; i++)
{
cout << "\n";
for (int j = 0; j < 2; j++)
cout << A[i][j] << ",";
}
c_exp = 0;
i1 = 0;
while (b % 2 == 0)
{
c_exp++;
b = b/2;
}
if (c_exp != 0)
{
B[i1][0] = 2;
B[i1][1] = c_exp;
i1++;
}
d = 3;
while (b != 1 && d <= b)
{
c_exp = 0;
while (b % d == 0)
{
c_exp++;
b = b/d;
}
if (c_exp != 0)
{
B[i1][0] = d;
B[i1][1] = c_exp;
i1++;
}
d = d+2;
}
cout << "\nMatricea B contine:";
for (int i = 0; i < i1; i++)
{
cout << "\n";
for (int j = 0; j < 2; j++)
cout << B[i][j] << ",";
}
return 0;
}
From now on I have to find if the first number of first array exist in the second array and after this I have to compare the exponents of the same number of both array and the lowest one I have to add it to product. After this I have to repeat the same proccess with the second number to the last one of the first array. The problem is that I don't know how to write this.I have to mention that this program isn't complete.
Any ideas?
If you need better solution then you can avoid array and use the below logic.
int main()
{
int a =12 ,b = 20;
int min = a>b ? a:b; // finding minimum
if(min > 1)
{
for (int i=min/2; i>1; i--)//Reverse loop from min/2 to 1
{
if(a%i==0 && b%i==0)
{
cout<<i;
break;
}
}
}
else if(min == 1)
{
cout<<"GCD is 1";
}
else
cout<<"NO GCD";
return 0;
}
You can also check the working example Greatest Common Divisor
I am not quite sure what you are trying to achieve with your code. It looks over complicated. If I were to find the biggest common divisor of two numbers I would do something like the following:
## This is not a correct implementation in C++ (but close to it) ##
Read the two integers **a** and **b**
int max_div(int a, int b){
int div = a > b ? a : b;
while (div != 1 && (a%div != 0 && b%div != 0)){
div--;
}
return div;
}
This function starts with the minimum of a and b as the highest possible common divisor and then works its way backwards until one of two possible outcomes:
It finds a common divisor (a%div == 0 and b%div == 0)
It reaches one (always a common divisor)
EDIT : Now returns one if no higher divisor is found. (Was returning zero which made no sense)

Competitive programming: Solution runs a bit too slow

This is a question from a ZCO (Zonal Computing Olympiad; Indian IOI qualifying contest) paper.
Basically, it revolves around finding the number of distinct pairs of elements from a set of numbers whose sum does not exceed a certain value.
My solution works on all except the last test case (on a certain private server, the test case itself is not available), on which it exceeds the 3-second time limit by half a second.
Am I missing something, algorithmically? A few pointers would be nice.
Here is my code:
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
int main() {
int n, k;
cin >> n >> k;
vector<int> hardness;
hardness.reserve(n);
int temp;
for(int i = 1; i <= n; ++i) {
cin >> temp;
if (temp < k) {
hardness.push_back(temp);
}
}
sort(hardness.begin(), hardness.end());
int mx = hardness.back(); //Max element
int chewableCombinations = 0, cur = 0;
for(int i = 0; i < hardness.size() - 1; ++i) {
cur = hardness[i];
if(cur == 0 || cur + mx < k) {
chewableCombinations += hardness.size() - i - 1;
continue;
}
for(int j = i + 1; j < hardness.size(); ++j) {
if(cur + hardness[j] < k) {
++chewableCombinations;
} else break; //we've crossed the limit
}
}
cout << chewableCombinations << endl;
}
If hardness[i]+hardness[j] < k then hardness[i]+hardness[m] < k for all m < j.
You don't have to check them all.

C++ heapsort confusion

This might be a weird question but I'm trying to figure out why the following code works.
It seems as though this code should be used where the heap elements index starts at 1 but it's starting at 0 and the sort is completed correctly.
I say that because the left child is calculated as (element*2) and the right child is (element*2 + 1). This would make the left child for the element with index 0 also have index 0.
#include <iostream>
using namespace std;
void siftDown(int numbers[], int root, int bottom) {
int done, maxChild, temp;
done = 0;
while ((root*2 <= bottom) && (!done)) {
if (root*2 == bottom)
maxChild = root * 2;
else if (numbers[root*2] > numbers[root*2 + 1])
maxChild = root * 2;
else
maxChild = root * 2 + 1;
if (numbers[root] < numbers[maxChild]) {
temp = numbers[root];
numbers[root] = numbers[maxChild];
numbers[maxChild] = temp;
root = maxChild;
} else {
done = 1;
}
}
}
void heapSort(int numbers[], int n) {
int i, temp;
for (i = n/2; i >= 0; i--) {
siftDown(numbers, i, n - 1);
}
for (i = n-1; i >= 1; i--) {
temp = numbers[0];
numbers[0] = numbers [i];
numbers [i] = temp;
siftDown(numbers, 0, i-1);
}
}
int main() {
int cases;
int n;
int count;
cin >> cases;
for (int i=0; i < cases; i++) {
cin >> n;
int array[n];
for (int j=0; j < n; j++) {
cin >> array[j];
}
heapSort(array, n);
for (int k=0; k < n; k++) {
cout << array[k];
}
cout << endl;
}
}
For the case when root = 0, there are two sub-cases: numbers[0] > numbers[1], or not. In the first, maxchild is set to 0. The next "if" clause - effectively "numbers[0] < numbers[0]" - necessarily evaluates to false, and so "done" is set to 1 and the loop terminates.
If numbers[1] >= numbers[0], then maxchild is set to 1. The next clause becomes "numbers[0] < numbers[1]" which may be true or may be false if numbers[0] == numbers[1]. If it is false, the loop terminates as before. If it is true, numbers[0] and numbers[1] are swapped - thus the larger number correctly moves to the top of the heap - and root becomes 1, the loop continues and in this case you understand how it works.
I think it's easiest to consider this case as a heap where the root only has one child (and all other nodes have two children as normal).