Complete Beginner: Null pointer issue? - c++

I have looking all over forums to try and understand this issue. The reasons I cannot fully understand the issue and why I cannot find a solution is because I am fairly new with C++ and I do not understand the error message.
This is my code in C++ that finds the number of possibilities from permutation or combination formulas. Every I try and compile and run, I get messages that say:
First-chance exception at 0x6a8613af (msvcr100d.dll) in
Combinations_Permutations.exe: 0xC0000005: Access violation reading
location 0x00000005. Unhandled exception at 0x6a8613af (msvcr100d.dll)
in Combinations_Permutations.exe: 0xC0000005: Access violation reading
location 0x00000005.
I've learned on many other forums that the "access violation reading location 0x00..." could definitely indicate null pointer. But I cannot see where I encounter such a null issue. Maybe my variables are being accessed globally, where they are not YET initialized?
Here is my code, I have been at it for a while... like I said I'm fairly new. So please inform me of my mistake(s). Thank you.
My code:
#include <iostream>
#include "conio.h";
using namespace std;
int run_combination(int n, int r);
int run_permutation(int n, int r);
int solve_factorial(int f);
int f_value = 1; //factorial value used recursively
int n_input, r_input;
char choice;
char order;
void main(){
//if user types choice as 'q', while loop ends
while(choice != 'q'){
printf("How many values? (1-9) \n");
printf("User: ");
cin >> n_input;//user input for variable n
printf("n_input: %i", n_input);
printf("\nHow many will be chosen at a time out of those values? (1-9)\n");
printf("User: ");
cin >> r_input; //user input for variable r
printf("\nDoes order matter? (y/n)\n");
printf("User: ");
cin >> order; //'y' if order is taken into consideration(permutation)
//'n' if order it NOT taken into consideration(combination)
int solution = 0; //temporary variable that represents the solution after running
//n and r through the permutation or combination formula
//if user input values for n and r are in between 1 and 9, then run
//combination or permutation
if (n_input <= 9 && n_input >= 1 && r_input <= 9 && r_input >= 1){
if (order == 'y')
solution = run_permutation(n_input, r_input);
else if (order == 'n')
solution = run_combination(n_input, r_input);
else
printf("\nError. Please type 'y' or 'n' to determine if order matters.\n");
//if n < r, run_permutation or run_combination returns 0
if (solution == 0){
printf("Error! You can't choose %i values at a time if there \n",
"are only %i total values. Type in new values next loop \n.", r_input, n_input);
}
else
printf("Number of possibilities: %s", solution);
}
else{ //else error message if numbers are out of range...
printf("Next loop, type in values that range from 1 to 9.\n");
}
//option 'q' to quit out of loop
printf("Type 'q' to quit or enter any key to continue.\n");
printf("User: ");
cin >> choice;
}
_getch();
}
/*
Returns solved combination of parameters n and r
Takes the form: n! / r!(n-r)!
*/
int run_combination(int n, int r){
if (n < r) //solution is impossible because you can't choose r amounnt at a time if r is greater than n
return 0;
int n_fac = solve_factorial(n); //n!
int r_fac = solve_factorial(r); //r!
int nMinusr_fac = solve_factorial(n-r); //(n-r)!
int solve = ((n_fac) / ((r_fac)*(nMinusr_fac))); // plugging in solved factorials into the combination formula
return solve;
}
int run_permutation(int n, int r){
if (n < r)
return 0;
int n_fac = solve_factorial(n);
int nMinusr_fac = solve_factorial(n-r);
int solve = ((n_fac) / (nMinusr_fac)); //plugging in factorials into permutation formula
return solve;
}
int solve_factorial(int f){
if (f-1==0 || f == 0){ //if parameter f is 1 or 0, return 1
int temp = f_value;
f_value = 1; //reset f_value so that f_value remains 1 at the start of every new factorial
return temp;
}
else{ //else multiply f_value by f-1
f_value *= f;
return solve_factorial(f-1);
}
}

This is a mistake:
printf("Number of possibilities: %s", solution);
solution is an int, not a null terminated string: use %d.
Using std::cout which is typesafe, instead of printf(), would have prevented this error:
std::cout << "Number of possibilities: " << solution;

The problematic line is:
printf("Number of possibilities: %s", solution);
You're telling printf that solution is a char*, and so it tries to dereference (char*)solution to print the contents of the "C-string" (presumably when solution has the value 5 in the case of your particular error message).
Change %s to %d, or use std::cout instead of printf to gain type-safety and avoid this sort of issue in the first place.

Related

I want to know the error in my code. This is to print sum of all even numbers till 1 to N

#include<iostream>
using namespace std;
int main(){
int i = 1;
int sum;
int N;
cout << "Enter a number N: ";
cin >> N;
while(i<=N)
{
if(i%2 == 0)
{
sum = sum + i;
}
else
{
i = i + 1;
}
}
cout << sum;
}
This is to print the sum of all even numbers till 1 to N.
As I try to run the code, I am being asked the value of N but nothing is being printed ahead.
For starters the variable sum is not initialized.
Secondly you need to increase the variable i also when it is an even number. So the loop should look at least like
while(i<=N)
{
if(i%2 == 0)
{
sum = sum + i;
}
i = i + 1;
}
In general it is always better to declare variables in minimum scopes where they are used.
So instead of the while loop it is better to use a for loop as for example
for ( int i = 1; i++ < N; ++i )
{
if ( i % 2 == 0 ) sum += i;
}
while(i<=N)
{
if(i%2 == 0)
{
sum = sum + i;
}
else
{
i = i + 1;
}
}
Let's step through this. Imagine we're on the loop where i = 2 and you've entered N = 5. In that case...
while(i <= N)
2 <= 5 is true, so we loop
if(i%2 == 0)
2 % 2 == 0 is true, so we enter this branch
sum = sum + i;
Update sum, then head back to the top of the loop
while(i <= N)
Neither i nor N have changed, so 2 <= 5 is still true. We still loop
if(i%2 == 0)
2 % 2 == 0 is still true, so we enter this branch again...
Do you see what's happening here? Since neither i nor N are updated, you'll continue entering the same branch and looping indefinitely. Can you think of a way to prevent this? What would need to change?
Also note that int sum; means that sum will have a garbage value (it's uninitialized). If you want it to start at 0, you'll need to change that to
int sum = 0;
You're looping infinitly when i is even because you don't increase it.
Better option would be this if you want to use that while loop :
while(i<=N)
{
if(i%2 == 0)
sum = sum + i;
i=i+1;
}
cout << sum;
If you don't need to do anything when the condition is false, just don't use an else.
No loops are necessary and sum can be evaluated at compile time if needed too
// use unsigned, the whole excercise is pointless for negative numbers
// use const parameter, is not intended to be changed
// constexpr is not needed, but allows for compile time evaluation (constexpr all the things)
// return type can be automatically deduced
constexpr auto sum_of_even_numbers_smaller_then(const unsigned int n)
{
unsigned int m = (n / 2);
return m * (m + 1);
}
int main()
{
// compile time checking of the function
static_assert(sum_of_even_numbers_smaller_then(0) == 0);
static_assert(sum_of_even_numbers_smaller_then(1) == 0);
static_assert(sum_of_even_numbers_smaller_then(2) == 2);
static_assert(sum_of_even_numbers_smaller_then(3) == 2);
static_assert(sum_of_even_numbers_smaller_then(7) == 12);
static_assert(sum_of_even_numbers_smaller_then(8) == 20);
return 0;
}
int main(){
int input; //stores the user entered number
int sum=0; //stroes the sum of all even numbers
repeat:
cout<<"Please enter any integer bigger than one: ";
cin>>input;
if(input<1) //this check the number to be bigger than one means must be positive integer.
goto repeat; // if the user enter the number less than one it is repeating the entry.
for(int i=input; i>0; i--){ // find all even number from your number till one and than totals it.
if(i%2==0){
sum=sum+i;
int j=0;
j=j+1;
cout<<"Number is: "<<i<<endl;
}
}
cout<<endl<<"The sum of all even numbers is: "<<sum<<endl;}
Copy this C++ code and run it, it will solve your problem.
There are 2 problems with your program.
Mistake 1
The variable sum has not been initialized. This means that it has(holds) an indeterminate value. And using this uninitialized variable like you did when you wrote sum = sum + i; is undefined behavior.
Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely on the output of a program that has undefined behavior.
This is why it is advised that:
always initialize built in types in local/block scope.
Mistake 2
The second problem is that you're not updating the value of variable i.
Solution
You can solve these problems as shown below:
int main(){
int i = 1;
int sum = 0; //INITIALIZE variable sum to 0
int N;
cout << "Enter a number N: ";
cin >> N;
while(i<=N)
{
if(i%2 == 0)
{
sum = sum + i;
}
i = i + 1; //update(increase i)
}
cout << sum;
}
1For more reading(technical definition of) on undefined behavior you can refer to undefined behavior's documentation which mentions that: there are no restrictions on the behavior of the program.

Finding Armstrong Number using C++

I'm writing a program for finding whether a given number is an Armstrong Number:
int main()
{
int n,rem,sum=0;
cout<<"Enter the Number for checking"<<endl;
cin>>n;
while(n!=0)
{
rem=n%10;
sum=sum+(rem*rem*rem);
n=n/10;
}
if(sum==n)
{
cout<<"Armstrong Number"<<endl;
}
else
{
cout<<"It's not a armstrong number";
}
return 0;
}
When I run it, it always reports "It's not a armstrong number", regardless of input.
I changed the code as follows, and got the correct result. But I don't understand why I need to assign input to n1 and do the operation - why can't I directly do the operation with n?
int main()
{
int n,rem,sum=0,n1;
cout<<"Enter the Number for checking"<<endl;
cin>>n;
n1=n;
while(n1!=0)
{
rem=n1%10;
sum=sum+(rem*rem*rem);
n1=n1/10;
}
if(sum==n)
{
cout<<"Armstrong Number"<<endl;
}
else
{
cout<<"It's not a armstrong number";
}
return 0;
}
In the line if (sum==n) your program compares sum and n. In the second program n is initial number entered by user. But in the first program n==0 (see the loop above it).
So, in the first program the check if (sum==n) works as if (sum==0). But value of sum is never 0 (except user entered 0). So, first program always returns "It's not a armstrong number".
And about style: It is much better to use functions instead of putting the whole logic into one main() function. For instance, you can create a function for calculation of the intermediate sum for cheching of Armstrong Number:
int getSumOfCubesOfDigits(int n)
{
int sum = 0;
while (n)
{
const int rem = n % 10;
sum += rem * rem * rem;
n = n / 10;
}
}
In this case your program will be much simpler and it will be hard to make the mistake you have in the first program of your question:
int main()
{
int n;
cout << "Enter the Number for checking" << endl;
cin >> n;
if(getSumOfCubesOfDigits(n) == n)
cout<<"Armstrong Number"<<endl;
else
cout<<"It's not a armstrong number";
return 0;
}
In the first program, the original number is entered into 'n'. The only problem in your logic is, you forgot that by the time you exit from the while loop, 'n' will no longer be your original number since you are repeatedly doing n=n/10, and hence 'sum==n' never satisfies even for an Armstrong number.
So before you enter the while loop, save the original number into another variable, say n1 (as done in the second program you provided), and only use n1 for operations, ie, n1=n1/10. Leave n alone so that, in the end 'n' will still contain the original number, which you can finally compare with 'sum' to find your answer.
Which number do you compare ? , in first program in while loop , n value is changed ( in this variable you get the input) and finally check with sum == n , so it always get condition fail.
So temp (n1) variable is required , to compare the final result
Your code is different in the second code block, you are still testing if sum=n.
In the second code block, if you tested if(sum=n1), I would suspect it would work the same.
I got this solution for finding an Armstrong Numbers
int main() {
for (int i=10; i<=9999; i++) {
int k = i,z = 1, s = 0, n = i;
while ((k/=10) > 0) z++;
for (int t = z; t; t--, n/=10) {
s += pow(n % 10, z);
}
if (i == s) cout << i << endl;
}
return 0;
}

Recursive solution for 3n+1

I just like to do simple recursion.
For a number if it is even then it'll approach to (number/2) and if odd then to (3*number+1). How many time it'll occur to reach 1.
for 10
10-> 5-> 16-> 8-> 4 -> 2 ->1
total process 6
long arr[10000];
long dp(int n)
{
if(n==2|| n==1) return 1;
if(arr[n]) return arr[n];
if(n%2==0) return arr[n]=1+dp(n/2);
else if(n%2==1) return arr[n]=1+dp(3*n+1);
return arr[n];
}
I've created function like this one and for some input like 999 or 907 causes segmentation fault.
I wanna know why?
And if I increase array size then its output correctly.
I wanna know why too?
Why its depending on array size as I've taken long as array element data type so it should output correctly for those input?
with 999, you reach 11392
with 907, you reach 13120
and those numbers are out of bound.
Live example
You are indexing the array out of bounds
For the inputs you are using, the variable n will exceed the array size 10000 during execution. This causes the program to access memory beyond its boundaries, resulting in a segmentation fault.
If you're trying to memoize the function, I'd suggest using std::map instead of a fixed array. This is an associative array which stores key-value pairs—in this case, each memoized input-output pair—and can quickly retrieve the value associated with a given key. Maps are ideally suited for this application as they can store this data using only as much memory as is actually necessary, automatically growing as needed.
You could also use std::vector, though this is not recommended. Vectors are like arrays, but they can be resized dynamically, avoiding the problem of indexing out of bounds. The drawback with this approach is that for certain inputs, a very large amount of memory may be required, possibly several gigabytes. If the program is compiled to a 32-bit binary rather than to a 64-bit binary, the program may crash at runtime when it fails to allocate enough memory for the vector.
Implementation using map
#include <iostream>
#include <map>
using namespace std;
long long dp(unsigned long long);
int main() {
unsigned long long n;
while(true) {
cout << "Enter a number, or 0 to exit: ";
cin >> n;
if(!cin) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cerr << "Invalid input, please try again." << endl;
continue;
}
if(n == 0)
return 0;
else
cout << dp(n) << endl;
}
return 0; // Unreachable
}
long long dp(unsigned long long n) {
static map<long long, long long> memo;
if(n == 2 || n == 1) return 1;
if(memo[n]) return memo[n];
if(n % 2 == 0) return memo[n] = 1 + dp(n / 2);
else if(n % 2 == 1) return memo[n] = 1 + dp(3 * n + 1);
return memo[n];
}
Implementation using vector
#include <iostream>
#include <vector>
using namespace std;
long long dp(unsigned long long);
int main() {
unsigned long long n;
while(true) {
cout << "Enter a number, or 0 to exit: ";
cin >> n;
if(!cin) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cerr << "Invalid input, please try again." << endl;
continue;
}
if(n == 0)
return 0;
else
cout << dp(n) << endl;
}
return 0; // Unreachable
}
long long dp(unsigned long long n) {
static vector<long long> arr;
if(arr.size() <= n)
arr.resize(n + 1);
if(n == 2 || n == 1) return 1;
if(arr[n]) return arr[n];
if(n % 2 == 0) return arr[n] = 1 + dp(n / 2);
else if(n % 2 == 1) return arr[n] = 1 + dp(3 * n + 1);
return arr[n];
}
The segmentation fault comes from overflowing the array. How about you do something like the following?
void rec(int n, int* steps) {
++(*steps);
printf("%d\n", n);
// termination step if 'n' equals 1
if(n == 1)
return;
if (n % 2 == 0)
rec(n/2, steps);
else
rec(3*n+1, steps);
}
int main(void) {
int steps = 0;
rec(10, &steps);
printf("Steps = %d\n", steps);
return 0;
}
Output:
10
5
16
8
4
2
1
Steps = 7
The code presented here agrees (of course) with Jarod's answer.
You are overflowing the array because the sequence value exceeds 9999.
If all you want to know is the number of processes that it takes, you should not be using array storage.
int numProcesses = 0;
int hailstone(int n) {
if (n == 1) {
return 1;
} // base case
++numProcesses; // if it wasn't the base case the method will do some work so increment numProcesses
if (n % 2 == 0) {
return hailstone(n / 2);
} // n is even
else {
return hailstone(3 * n + 1);
} // n is odd
}
This is untested but I think it should work, and after it finally returns numProcesses should equal the number of times the method was called (so long as it was not called with a parameter of 1).

run time error - non zero exception

my programming teacher gave me this problem to code it in c :
given array of N integers A and a number K. During a turn the maximal value over all Ai is chosen, let's call it MAX. Then Ai =
MAX - Ai is done for every 1 <= i <= N. Help Roman to find out how will the array look like after K turns.
Input
The numbers N and K are given in the first line of an input. Then N integers are given in the second line which denote the array A.
Output
Output N numbers on a single line. It should be the array A after K turns.
Constraints
* 1 <= N <= 10^5
* 0 <= K <= 10^9
* Ai does not exceed 2 * 10^9 by it's absolute value.
Example
Input:
4 1
5 -1 7 0
Output:
2 8 0 7
and my code to this problem is :
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
long int Max(long int *arr, int low, int high)
{
long int max,i;
max = arr[low];
for(i=0;i<=high;i++)
{
if(max<=arr[i])
max = arr[i];
}
return max;
}
/* Driver program to test above function */
int main()
{
long int max,*arr;
long int n,k,c1,c2,c3,i,j;
c1 = (long int)pow(10,5);
c2 = (long int)pow(10,9);
c3 = 2*c2;
scanf("%ld %ld",&n,&k);
if(n<1||n>c1)
exit(1);
else if(k<0||k>c2)
exit(1);
else
{
arr = (long int *)malloc(sizeof(int)*n);
for(i=0;i<n;i++)
{
scanf("%ld",&arr[i]);
if(abs(arr[i])>c3)
exit(1);
}
if(k%2 == 0)
{
for(i=0;i<2;i++)
{
max = Max(arr, 0, n-1);
for(j=0;j<n;j++)
{
arr[j] = max-arr[j];
if(abs(arr[j])>c3)
exit(1);
}
}
}
else if(k%2 != 0)
{
max = Max(arr, 0, n-1);
for(j=0;j<n;j++)
{
arr[j] = max-arr[j];
/*if(abs(arr[j])>c3)
exit(1);*/
}
}
/* for(m=0;m<n;m++)
printf("%ld ",arr[m]);
printf("\n");*/
for(i=0;i<n;i++)
printf("%ld ",arr[i]);
printf("\n");
}
return 0;
}
i executed this code on gcc compiler in ubuntu, it is working perfectly with all the constraints satisfied but when I uploaded this code on my teacher's portal which has a compiler and executed the code, it said Runtime error -
nzec which means a non-zero exception which is used to signify that main() does not have "return 0;" statement or exception thrown by c++ compiler.
Please, can anyone help me what is wrong in my code as there is a return 0; statement in my code. Please Help.
Everyone has pointed out multiple use of exits ... Can I reduce them using any other way in place of exit()?
My guess is that it has to do with the various exit(1) statements you have for error conditions.
As pointed out by Dave Costa, exit(1) could be the cause
Another possible problem is the size of the allocated array:
arr = (long int *)malloc(sizeof(int)*n);
should be:
arr = malloc(sizeof(long int)*n);
And note that you don't need to use pow for constants:
c1 = (long int)pow(10,5);
c2 = (long int)pow(10,9);
could be replaced with:
c1 = 1e5L;
c2 = 1e9L;

how do you store char and int in same variable?

i know that int and char cant be specified by different data types and char basically represents the ASCII values. what confuses me is storing them in the SAME data type which can be used later on. For example, if i were to input int and char both type of data from the user in variable x, how would i define the variable? like with what type of it?
lets say you were to input integers from the user and when the user enters a symbol('='), the program ends.
void main()
{
int count, flag = 0;
int i = 0;
int x = 0;
const int ASCII_VALUE_OF_EQ = '='
x = ASCII_VALUE_OF_EQ;
for (i = 0; i <=10; i++){
cout << "Enter the number = ";
cin >> x;
if (x == ASCII_VALUE_OF_EQ)
break;
}
//to find if the number before '=' was prime
int m = 2; int c = 0;
while (m < x)
{
if (x%m == 0){
c++;
break;
}
m++;
}
if (c == 0){
cout << x << " is a Prime number"<<endl<<"here are all the prime numbers that come before '='" << endl;
for (int a = 2; a <= x; a++)
{
int c = 0;
for (int b = 1; b <= a; b++)
{
if (a%b == 0)
c++;
}
if (c == 2){
cout << a << endl;
continue;
}
}
}
getch();
}
Here you want to write a smart piece of code that interprets different kind of input strings differently. If you are searching for a ready-made C++ function that interprets a string exactly as you want then you will be disappointed. There is no such magical function. :-(
Lets say I write in "0" as the input for your program. Do I want zero int(0) or the integral value of ascii('0') (int(48))??? Your magical string interpreter artificial intelligence function has to find out what I want! :-)
Read in one line of input as string
Find out how do you want to interpret the string with your magic AI function. Here are a few tips how to detect what the user wants: If the string length is 1 and it isn't a digit ('0'-'9') then you could treat it as a character (and you could use the first character of the string as an integer or you could exit your loop in some other cases - for example if it is a '=' character) otherwise you could treat it as the string representation of an integer and you could actually convert it to an integer with the std::stoi standard library function.
Of course you can use any other methods to detect the contents of the input string, I just gave you a tip as a kickstarter.
You may face other differences later, for example what happens if the user enters the input by specifying a few space characters before the actual input (and so on...) but these are just error handling codepieces. First get your code working with "correct" input.