Access violation reading location 0x50F9BF08 - c++

I have written a code that solves 3n + 1 problem
but when i run it and input (1 200000) i get
Access violation reading location 0x50F9BF08
I don't know what this exception is and I'll be very thankful if someone helps
here's my code:
#include "iostream"
#include "conio.h"
using namespace std;
#define MAX 1000000
long int cycleLengthResult[MAX] = { 0 };
long int cycleLength(long int num)
{
if (num > MAX)
{
if (num % 2 == 0)
return 1 + cycleLength(num / 2);
else
return 1 + cycleLength(3 * num + 1);
}
else if (cycleLengthResult[num] == 0)
{
int count = 0;
if (num == 1)
count = 1;
else if (num % 2 == 0)
count = 1 + cycleLength(num / 2);
else
count = 1 + cycleLength(3 * num + 1);
cycleLengthResult[num] = count;
}
return cycleLengthResult[num];
}
int main()
{
int i, j;
long int max;
while (cin >> i >> j)
{
max = 0;
cout << i << " " << j << " ";
if (i > j)
{
int temp;
temp = j;
j = i;
i = temp;
}
for (int k = i; k <= j; k++)
{
cycleLength(k);
if (cycleLengthResult[k] > max)
max = cycleLengthResult[k];
}
cout << max << endl;
}
_getch();
return 0;
}

There's a pretty good chance you are overrunning the cycleLengthResult array. Certainly the expression in the if (num > MAX) clause is suspicious - if num is odd it will certainly exceed the array boundaries.
One way to figure this out easily is to not use a raw array, but a std::array, and access it not using operator[], but using member function at(). at() has the additional bonus of doing bounds checking for you, so you can see where your function fails.

You are overflowing the limit of the long int. If you would have debugged the code you'd see that the issue happens when you recursively call return 1 + cycleLength(3 * num + 1); with num being 827370449, thus 3 * num + 1 is 2482111348 (which is more than LONG_MAX or 2147483647) and subsequently cycleLength is called with num being -1812855948. You can fix this by using an unsigned value long int cycleLength(unsigned long int num). I did not devote time to look at the actual algorithm but you may be better of with a 64bit value for num if the value grows really big.

Related

Converting an integer into it's binary equivalent

I have an assignment to make a program that should convert a number from it's integer value to a binary value. For some reason my array is always filled with zeroes and won't add "1"'s from my if statements. I know there are probably solutions to this assignment on internet but I would like to understand what is problem with my code. Any help is appreciated.
Here is what I tried:
#include <iostream>
/*Write a code that will enable input of one real number in order to write out it's binary equivalent.*/
int main() {
int number;
int binaryNumber[32] = { 0 };
std::cout << "Enter your number: ";
std::cin >> number;
while (number > 0) {
int i = 0;
if ((number / 10) % 2 == 0) {
binaryNumber[i] = 0;
}
if ((number / 10) % 2 != 0) {
binaryNumber[i] = 1;
}
number = number / 10;
i++;
}
for (int i = 31; i >= 0; i--) {
std::cout << binaryNumber[i];
}
return 0;
}
You need to remove number/10 in both the if statements. Instead, just use number. you need the last digit every time to get the ith bit.
Moreover, you need to just half the number in every iteration rather than doing it /10.
// Updated Code
int main() {
int number;
int binaryNumber[32] = { 0 };
std::cout << "Enter your number: ";
std::cin >> number;
int i = 0;
while (number > 0) {
if (number % 2 == 0) {
binaryNumber[i] = 0;
}
if (number % 2 != 0) {
binaryNumber[i] = 1;
}
number = number / 2;
i++;
}
for (int i = 31; i >= 0; i--) {
std::cout << binaryNumber[i];
}
return 0;
}
The first thing is the variable 'i' in the while loop. Consider it more precisely: every time you iterate over it, 'i' is recreated again and assigned the value of zero. It's the basics of the language itself.
The most relevant mistake is logic of your program. Each iteration we must take the remainder of division by 2, and then divide our number by 2.
The correct code is:
#include <iostream>
int main()
{
int x = 8;
bool repr[32]{};
int p = 0;
while(x)
{
repr[p] = x % 2;
++p;
x /= 2;
}
for(int i = 31; i >= 0; --i)
std::cout << repr[i];
return 0;
}
... is always filled with zeroes ... I would like to understand what is problem with my code
int i = 0; must be before the while, having it inside you only set the index 0 of the array in your loop because i always values 0.
But there are several other problems in your code :
using int binaryNumber[32] you suppose your int are on 32bits. Do not use 32 but sizeof(int)*CHAR_BIT, and the same for your last loop in case you want to also write 0 on the left of the first 1
you look at the value of (number / 10) % 2, you must look at the value of number % 2
it is useless to do the test then its reverse, just use else, or better remove the two ifs and just do binaryNumber[i] = number & 1;
number = number / 10; is the right way when you want to produce the value in decimal, in binary you have to divide by 2
in for (int i = 31; i >= 0; i--) { except for numbers needing 32 bits you will write useless 0 on the left, why not using the value of i from the while ?
There are some logical errors in your code.
You have taken (number/10) % 2, instead, you have to take (number %2 ) as you want the remainder.
Instead of taking i = 31, you should use this logic so you can print the following binary in reverse order:
for (int j = i - 1; j >= 0; j--)
{
cout << BinaryNumb[j];
}
Here is the code to convert an integer to its binary equivalent:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
// function to convert integer to binary
void DecBinary(int n)
{
// Array to store binary number
int BinaryNumb[32];
int i = 0;
while (n > 0)
{
// Storing remainder in array
BinaryNumb[i] = n % 2;
n = n / 2;
i++;
}
// Printing array in reverse order
for (int j = i - 1; j >= 0; j--)
{
cout << BinaryNumb[j];
}
}
// Main Program
int main()
{
int testcase;
//Loop is optional
for(int i = 0; i < testcase; i++)
{
cin >> n;
DecToBinary(n);
}
return 0;
}

highest power of 2 behind a number

I am writing a code to give numbers in a line and the inputs finish with zero then wirtes the highest power of 2 smaller or equal the inputs in a line.
it doesn't work.
#include<iostream>
#include<stdio.h>
using namespace std;
int highestPowerof2( int n)
{
static int result = 0;
for (static int i=n; i>=1; i--)
{
if ((i & (i-1)) == 0)
{
result = i;
break;
}
}
return result;
}
int main() {
static int num ;
do{
cin>>num ;
}
while(num=!0);
cout<<highestPowerof2(num)<<"\n";
return 0;
}
The most surprising thing in your code is this:
do{
cin>>num ;
}
while(num=!0);
You keep reading num from user input until num == 0. I have to admit that I dont really understand the rest of your code, but for num == 0 calling the function highestPowerof2(num) will always result in 0.
Perhaps you wanted to repeat the program until the user decides to quit, that could be
do{
cin>>num ;
cout<<highestPowerof2(num)<<"\n";
} while(num=!0);
PS: the other "surprising" thing is that you use static in places where it does not really make sense. Better simply remove it.
Here is another approach that is a little bit faster for large n. For example if n = 2^31 - 1, then the original loop would need to iterate 2^30 - 1 = 1,073,741,823 times, whereas this loop only needs a single iteration (provided sizeof(int) == 4):
#include <iostream>
#include <stdio.h>
using namespace std;
int highestPowerof2( int n)
{
if (n < 0) return 0;
int result = 0;
int num_bits = sizeof(int) * 8;
unsigned int i = 1 << (num_bits - 1);
while(i > 0) {
if (n >= i) return i;
i >>= 1;
}
return 0;
}
int main() {
int num ;
while (1) {
cin >> num;
cout << highestPowerof2(num) << "\n";
if (num == 0) break;
}
return 0;
}

How to use less memory in Sieve_of_Eratosthenes

I'm coding on a leetcode-like platform. There is a task: counter the number of primes below a given bound.
I used the algorithm: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
I copy the code from here: https://www.geeksforgeeks.org/sieve-of-eratosthenes/ , except that I make false represents isPrime to avoid using memset. Here is my code:
void SieveOfEratosthenes(int n)
{
bool *prime = new bool[n+1](); // initialized by false by default
for (int p=2; p*p<=n; p++)
{
if (prime[p] == false)
{
for (int i=p*p; i<=n; i += p)
prime[i] = true;
}
}
for (int p=2; p<=n; p++)
if (prime[p])
cout << p << " ";
}
However, when I execute it, the platform tells me that I used too much memory in the case of 100 000 000 as the enter.
I've checked that sizeof(bool) equals to 1.
Is there some way to use less memory for this piece of code?
A couple of suggestions:
use a bit array representing only odd numbers
break the problem up into segments so the partial sieve uses much less memory
#Kim Walish has a fast C++ version here:
https://github.com/kimwalisch/primesieve/wiki/Segmented-sieve-of-Eratosthenes
You can make it use less memory still by always limiting the segment size to the L1 cache size, and by changing the IsPrime array to also be a bit array of odd numbers.
This is a memory optimized implementation of the sieve of eratosthenes. The basic idea is that, you only need to store the status of the odd numbers. Rest of it is similar to the normal implementation.
#include <iostream>
class Solution {
public:
int countPrimes(int n) {
//if(n <= 1) return 0; // including n
if(n <= 2) return 0; // number of primes less than 0 / 1 / 2 is 0
const int MAXN = 1500000 + 5; // adjust MAXN accordingly
// finding prime from 1 up to N
int status[(MAXN >> 1) + 1]; // we need space for only the odd numbers
// works well up to 1.5 * 10 ^ 6, for numbers larger than that, you need to adjust the second operand accordingly
int prime[115000 + 1000]; // prime number distribution , pi(x) = x/ (ln(x) - 1) , adjust this according to MAXN
// If status[i] = 0 -> i is prime
// If status[i] = 1 -> i is not prime
for(int i = 1 ; i <= (n >> 1) ; ++i) status[i] = 0; // for every i , 2 * i + 1 is the odd number, marking it as prime
int sqrtN = static_cast <int> ((sqrt (static_cast <double> (n))));
// computing sqrt(N) only once because it is costly computing it inside a loop
// only accounting the odd numbers and their multiples
for(int i = 3 ; i <= sqrtN ; i += 2){
if(status[i >> 1] == 0){
// if this is still a prime then discard its multiples
// first multiple that needs to be discarded starts at i * i
// all the previous ones have already been discarded
for(int j = i * i ; j <= n ; j += (i + i)) {
//printf("Marking %d as not prime\n",j);
status[j >> 1] = 1;
}
}
}
int counter = 0;
prime[counter++] = 2;
for(int i = 3 ; i <= n ; i += 2){
if(status[i >> 1] == 0){
prime[counter++] = i;
}
}
if( (n & 1) && !status[n >> 1]) counter--; // if n is prime, discard n
std::cout << "Number of primes less than " << n << " is " << counter << "\n";
for(int i = 0 ; i < counter; ++i){
std::cout << prime[i];
if(i != counter - 1) std::cout << "\n";
}
std::cout << "\n";
return counter;
}
};
int main(int argc, char const *argv[])
{
Solution solution;
int n; std::cin >> n;
solution.countPrimes(n);
return 0;
}

C++ gdb error reading variable: Cannot access memory at address

I am trying to solve a problem that it want the program to output the result of n^84601. (n=0,1,...,10)
Therefore, I try to solve it by using big integer, and it works well in small number, but segfault in bigger ones.
#include <stdlib.h>
#include <iostream>
using namespace std;
const int MX = 100000;
struct BigInt {
int ar[MX];
int len;
BigInt(int n) {
int i = 0;
while (n != 0) {
ar[i] = n % 10;
n /= 10;
i++;
}
len = i;
}
BigInt times(BigInt x) {
BigInt tmp(0);
for (int i = 0; i < len; i++) {
for (int j = 0; j < x.len; j++) {
int r = ar[i] * x.ar[j] + tmp.ar[i + j];
tmp.ar[i + j] = r % 10;
tmp.ar[i + j + 1] += r / 10;
}
}
for (int i = min(len + x.len, MX - 1);; i--) {
if (tmp.ar[i] != 0) {
tmp.len = i + 1;
break;
}
}
return tmp;
}
void print() {
for (int i = len - 1; i >= 0; i--) {
cout << ar[i];
}
cout << endl;
}
};
BigInt poww(BigInt a, int n) {
if (n == 1) {
return a;
}
BigInt x = poww(a, n / 2);
BigInt y = x.times(x);
if (n % 2 == 1) {
y = y.times(a);
}
return y;
}
int main(void) {
ios::sync_with_stdio(false);
int n;
while (cin >> n) {
if (n == 0)
cout << 0 << endl;
else if (n == 1)
cout << 1 << endl;
else
poww(BigInt(n), 86401).print();
}
return 0;
}
When I change the MX in to 10000 and 86401 into 864, it can correctly caculate 2^864. But it will segfault with 2^86401.
You have a stack overflow.
Your BigInt object is quite large: it contains 100001 ints, which is usually 400,004 bytes.
You allocate several of these on the stack (some are unnecessary: you should really pass arguments by const reference).
You have recursion.
A typical stack size limit is 8MB.
Combine above statements together, and you can see that you can have at most 20 BigInts on the stack at one time. Your recursion depth is at least 17, so creating more than one BigInt on the stack for each recursive call is guaranteed to fail.
There are a few solutions:
use more efficient encoding -- currently you are using int to hold one digit, unsigned char would be more appropriate
allocate space for digits on heap instead of on the stack. If you do that, be aware of the rule of five.

Wrong Solution if Memoization is added to Recursion

I have created a DP program but the problem is that I get correct answers when I don't use memoization. As soon as I introduce memoization, I start getting the wrong answers for some problems
Here is the code in C++ 14 with memoization turned off (By commenting)
#include <iostream>
#include <math.h>
#include<algorithm>
using namespace std;
int max_Number_of_turns;
int dp[9999][1000];
int changeTheDigit(int n, int d) {
int rem = n % (int) (pow(10, 4 - d));
n /= (pow(10, 4 - d));
int x = n % 10;
n /= 10;
if (x == 9) x = 0;
else x = x + 1;
n = n * (10) + x;
n = n * (pow(10, 4 - d)) + rem;
return n;
}
int minMax(int n, int t) {
int ans =0;
//if(dp[n][t]>=0) { return dp[n][t];}
if (t > max_Number_of_turns) return n;
int N;
for (int i = 0; i < 4; i++) {
N = changeTheDigit(n, i + 1);
if (t % 2 == 0) {
//Manish chance
if(ans==0) ans=minMax(N, t+1);
else ans = min(ans, minMax(N, t + 1));
} else {
//Nitish Chance
ans = max(ans, minMax(N, t + 1));
}
}
//cout << ans << endl;
dp[n][t]=ans;
return ans;
}
using namespace std;
int main() {
int T, N, M;
cin >> T;
while (T--) {
cin >> N >> M;
max_Number_of_turns=M;
for(int i=0;i<9999;i++)
for(int j=0;j<1000;j++)
dp[i][j]=-1;
if(minMax(N,1)>N){
cout << "Nitish" << endl;
}
else{
cout << "Manish" << endl;
}
}
return 0;
}
Turn the memoization comment on (i.e. remove the comments from this line)
if(dp[n][t]>=0) { return dp[n][t];}
and my code will give wrong answers to some problems
For example, let us consider the input
1
4569 12
Original Correct Solution is Manish
But If I turn on memoization, My solution is Nitish
Can you suggest me that what am I doing wrong here
Also, a fun fact is that, if the change the DP code from
if(dp[n][t]>=0) { return dp[n][t];}
to
if(dp[n][t]>0) { return dp[n][t];}
Then everything is fine
Your problem is that the values for n and/or t are not checked and so could cause out-of-bounds issues with the array. You can see that if you insert the following at the start of your minMax function:
if (n < 0 || n >= 9999) cout << "n invalid at " << n << '\n';
if (t < 0 || t >= 1000) cout << "t invalid at " << t << '\n';
Running that with your sample input gives warnings before outputting the result:
n invalid at 9999
n invalid at 9999
n invalid at 9999
To fix this, you can just ensure you only use memoisation when you have enough storage for it, first when checking the value:
if (n >= 0 && n < 9999 && t >= 0 && t < 1000 && dp[n][t] >= 0)
return dp[n][t];
and, second, when storing the value:
if (n >= 0 && n < 9999 && t >= 0 && t < 1000)
dp[n][t] = ans;