Why does the program crash when the function is called in c? - c

I recently had to create a program where the user enters a certain integer N. After that, my int main() had to call a seperate function, int getNextFibonacciNumber(void), which calculates the Nth term in the fibonacci sequence and then prints it. When I compile the code, Vode::Blocks says that there aren't any errors or warnings. This said, when I try to run the program, it automatically crashes. I have read it and re-read it but I am not able to see where it all went wrong. Would anyone be able to shed some light on this mysery? Thank you very much! When the program crashes, it says: filename.exe has stopped working. A problem caused the program to stop working correctly. Windows will close the program and notify you if a solutions is available. However, when the code is compiled in Code::Blocks, everything is fine.
#include <stdio.h>
#include <stdlib.h>
int getNextFibonacciNumber(void);
int main()
{
int N, fibonacci[N];
printf("Enter a positive integer:");
scanf("%d", &N);
printf("The %d th term in the Fibonacci sequence is: %d", N, getNextFibonacciNumber());
}
int getNextFibonacciNumber()
{
int N, i, fibonacci[N];
fibonacci[0] = 0;
fibonacci[1] = 1;
for(i = 2; i < N+1; i++)
{
fibonacci[i] = fibonacci[i-1] + fibonacci[i-2];
}
return(fibonacci[N-1]);
}

The problem is, that this
int main()
{
int N, fibonacci[N];
invokes undefined behavior. N is not initialized, but used as a C99 variable length array size specifier. Reading a value from a uninitialized variable invokes UB.
To fix this issue you have to write
int main()
{
int N;
printf("Enter a positive integer:");
scanf("%d", &N);
int fibonacci[N];
However there's another problem, namely that you have the same UB causing construct in getNextFibonacciNumber. You have to fix that to. Also the number entered into N is not "communicated" to getNextFibonacciNumber, so I highly doubt that this program worked at all, even if it didn't crash.

Code::Blocks (or rather the compiler Code::Blocks calls) only checks if you have written "legal" c code. It does not (and can not) check if your program does what you want, if your program will exit at any point (or simply run forever), if your program causes errors and crashs and stuff like this.
When you say
int N, fibonacci[N];
I guess you want to create an integer N and an array of the same size. However right now you create an integer N (that has some "random" value, presumably 0) and an array of the FIXED size N.
If you change N late on in your program this does not affect the size of your array "fibonacci" in any way. So if your N was by chance 0 at the beginning of your program than you have created an array of size 0. Even if you read a value (say 5) from the console input. Trying to read and write to this array causes problems.
Moving the part
int fibonacci[N];
below your "scanf" line will fix this problem. At this point N is initialized (and not some random number).
Also be aware that the variable N in the main function
int main()
has no connection at all to the N variable in your function
int getNextFibonacciNumber()
The second N is a newly created variable (again set to some "random" value). If you want to pass data from one function to another you should do it by passing it as an argument in brackets:
int getNextFibonacciNumber( int N)

Related

Getting segmentation fault after while loop

Hi i have a project for tommorrow which i want to finish but im stuck. Im pretty new at this so don't be harsh.Basicly i want my program to ask how many numbers did the user play. How much money, after it asks for the lottery numbers and puts then in a border,then it asks for the users numbers,puts in on a second border and then i want to compare the 2 of them and if they have a same number it will add to 'sum'.
#include <stdlib.h>
int main()
{
int k[20],i;
int k2[12],f;
int numbers,sum,n,l,num;
float money,winnings;
l=0;
sum=0;
printf("How many numbers from 1 to 12?\n");
scanf("%d",&num);
printf("How much money?\n");
scanf("%f",&money);
for (i=0;i<19;i++)
{printf("Give lottery numbers\n");
scanf("%d",&k[i]);}
while (l<num){
printf("Give your numbers\n");
scanf("%d", k2 + f); !!fixed!!
l++;}
for (f=0;f<num;f++){
for (i=0;i>19;i++){ !!fixed!!
if ((k[i])==(k2[f])) !!! and here i think its a mistake.
{
sum=sum+1;
}
}
}
printf("You got %d numbers out of %d",sum,num);
if ((sum=1) && (num=1));
{winnings=(money*2,5);
printf("Won %f",winnings);}
if ((sum=1) && (num=2));
{winnings=(money*1);
printf("won %f",winnings);}
if ((sum=2) && (num=2));
{winnings=(money*5);
printf("Won %f",winnings);}
system("pause");}
It doesn't appear that f has ever been initialized to anything. Therefore,
scanf("%d",k2[f]);
Will result in undefined behavior, and is the likely cause of the crash.
Additionally, you need to fix your indentation. Furthermore, your loop is off by one. You initialize l to 1, then execute the following loop, whose apparent purpose is reading num numbers:
while (l<num){
So, if, for example, "1" was entered, in order to read only one number, the body of the loop will never execute, since the comparison "1<1" will be false.
It's likely there are other problems with this code, hard to analyze it due to bad indentation.
This loop
for (i=0;i=19;i++){
will never end since i=19 will evaluate to always true.
I think that the intention was:
for (i=0;i<19;i++){
Instead of l, what you probably intended, you are using f, which, as Sam Varshavchik spotted already, is not initialized.
Additionally, you are not passing a pointer to scanf: scanf("%d", k2[f]);. You need scanf("%d", k2 + l); instead, or scanf("%d", &k2[l]), if you prefer.

Why do I get segmentation fault in C? [duplicate]

This question already has answers here:
segmentation fault using scanf with integer
(2 answers)
Closed 7 years ago.
Why this question is not duplicate?
The problem can't be at scanf, as it is given by the hackerrank and I can't modify the code! Also, test cases are automated, given by hackerrank. We can trust them with input reading. There is some bug in my logic of finding two elements in array, couldn't find it though :|
Note: I can't modify main method, as mentioned earlier. Re-iterating it. Why can't I modify? It is because the method is given by the portal. I can't change it. It reads the input and calls my method through some automated scripts, I've no control over it. So, please don't tell me to modify main method.
I was trying some practice problems in hackerrank in C language and some of the test cases started throwing Segmentation fault for following problem. I've tried understanding it for more than 2 hours now and couldn't think of any test case which will throw segmentation fault. I'm stuck :|
Problem statement:
Given an array and a number. Find if there are 2 elements in array, whose sum is equal to given number. If number are present return 1, otherwise 0.
pretty easy, huh? I thought the same and coded it as follows,
int compFunc (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
int isSumPossible(int a[], int L, int N ){
/*L: Length of the array */
if(a==NULL) return 0;
if(L<=1) return 0;
int left=0, right=L-1;
qsort(a,L,sizeof(int),compFunc);
while(left<right)
{
if(a[left]+a[right]==N) return 1;
else if(a[left]+a[right]<N) left++;
else right--;
}
return 0;
}
int main() //given by hackerrank, I can't modify main method
{
int N; scanf("%d", &N); //fixed &N - it was correctly given in code, I missed it while typing it here.
int a[100004], i=0;
//read input into array a, based on N
int x;scanf("%d", &x); //fixed &x - it was correctly given in code, I missed it while typing it here.
printf("%d", isSumPossible(a,N,x));
}
Please assume all the header files required are included. Now, when I ran the code, most of the test cases passed and for some test cases they showed Segmentation fault. Unfortunately test cases aren't visible to me :|. I've gone through my code more than 10 times & I don't understand in which scenario I would get Segmentaion fault. Can anyone help me in understand which scenario am I missing in my code and why do I see segmentation fault?
The problem is in the scanfs in the main part of the code.
If you look at documentation the function description even says:
Reads data from stdin and stores them according to the parameter format into the locations pointed by the additional arguments.
This means you must give it a memory address to write data to. By adding & to both of your integer variables in your main the problem is solved.
int main()
{
int N; scanf("%d", &N);
int a[100004], i=0;
//read input into array a, based on N
int x;scanf("%d", &x);
printf("%d", isSumPossible(a,N,x));
}

Get exception error in C when trying to loop array

//Program Written By: Andre Chitsaz-zadeh
//Program Written On: 10/7/12
//Program calculates book cost for multiple book orders. Program written using multiple functions.`
#include <stdio.h>
#define SIZE 5
void inputData();
int main ()
{
inputData();
}
void inputData()
{
int i = 0;
int costs[5];
printf( "\nPlease enter five products costs.\n" );
while(i < 5)
{
scanf("%d", costs[i]);
i = i + 1;
}
}
Why do I get in exception error? The program looks simple enough! It compiles without problems but as soon as I input a number it says that "this program has stopped working". Thanks!!
scanf("%d", costs[i]);
Should be:
scanf("%d", &costs[i]);// &cost[i] gets the address of the memory location you want to fill.
It should be
while(i < 5) {
scanf("%d", &costs[i]);
i = i + 1;
}
a little typo I assume, anyway you need to provide the address of the element of the array you want to scan the integer into.
I would guess it's this line:
scanf("%d", costs[i]);
It should be:
scanf("%d", &costs[i]);
scanf needs a pointer to the variable in which it should put the read result.
This looks like a homework question, judging by the comment about the program have multiple functions. If functions are new, then pointers have probably not been covered yet. In that case, read my explanation as:
scanf needs a & before the variable in which it should put the read result. You'll learn why in a few weeks.
I think you'll need to change you scanf line to
scanf("%d", &costs[i]);
You need to pass the address of the int to have user input written to it. Your current code passes the value of costs[i]. This is undefined so will point to an unpredictable, and probably not writeable, location in memory.

10 element array

My teacher gave an assignment to me. The question is below:=
Write a program that prompts the user to enter 10 double numbers. The program should accomplish the follwing:
a. Store the information in a 10-element array.
b. Display the 10 numbers back to the user.
I could do all of the above in main().
Hint: You should use loops, not hardcode the values 0 through 9. It should be easy to convert your program to accept 1000 numbers instead of 10.
For a bonus mark, do at least one of the tasks (a or b) in a separate function. Pass the array to the function; do NOT use global (extern) variables.
I confused above. I wrote a program in the source code. Am I doing wrong? It is below:=
#include<stdio.h>
int main(void)
{
int number[10];
int i;
for (i = 0; i <10; i++)
printf("%d.\n", i, number[i]);
printf("\n\nPress [Enter] to exit program.\n");
fflush(stdin);
getchar();
return 0;
}
Thanks.
Not too bad so far, I'd like to make the following comments:
if you need to input double numbers, you should probably use double rather than int.
you need a statement (maybe in your current loop but possibly in another loop preceding the current one) which inputs the numbers. Look into scanf for this.
Using %d with printf is for integers, not doubles. You will have hopefully already figured out the format string to used when you looked into scanf above.
Bravo for using the correct int main(void) form and for not including conio.h :-)
Once you've figured those bits out, then you can worry about doing it in a separate function.
Based on the code you have given above, I would suggest reading up on the following:
scanf
functions in C, particularly passing arrays to functions: this link should be good.
Note to OP: If you were able to do (a) and (b) in main(), the code above is not complete. It would be nice the functions you created for getting (a) and (b) above done for getting to the root of your "confusion".
Let me know in case you need more help.
HTH,
Sriram
Try this it may sloves your problem.
#include<stdio.h>
int main(void)
{
double number[10];
int i;
printf("Enter double numbers:");
for (i = 0; i <10; i++)
scanf("%lf",&number[i] );
printf("The numbers you entered are:");
for (i = 0; i <10; i++)
printf("%lf\n",number[i] );
return 0;
}

Strange behaviour in a C code under gcc 4.4.3

I came across this piece of code today while tutoring some students in a C programming language course.
The exercise asked to implement two functions. The first one scans input from a user and the second displays what has been previously scanned.
The code I came across is the following:
#include <stdio.h>
void myInput(int i,int n)
{
int cpt;
int tab[n];
for ( cpt=0; cpt<n; cpt++)
{
printf("Enter a number :");
scanf("%d",&i);
tab[cpt]=i;
}
}
void myDisp (int n)
{
int tab[n];
int cpt;
for ( cpt=0; cpt <n; cpt++)
{
printf("%d ", tab[cpt]);
}
}
int main()
{
int n; int i;
printf(" Entrer the numbers of elements you want: \n");
scanf("%d \n",&n);
int tab[n];
myInput(i,n);
myDisp(n);
}
Although this code is full of inconsistencies, it does actually work under gcc 4.4.3: it displays the numbers that have been input!!!!!!
Does anyone understands how come these code works?
Thanks very much
If that works, it's through sheer dumb luck. What is printed in myDisp is uninitialized stack, which may or may not contain the data that was put into similarly named variables in myInput. Related reading
Here's an easy way to break it with do-nothing code:
void myInput(int i,int n)
{
// Add some variables to mess up the stack positioning.
int breaker;
int cpt;
int stomper;
int tab[n];
int smasher;
for ( cpt=0; cpt<n; cpt++)
{
printf("Enter a number :");
scanf("%d",&i);
tab[cpt]=i;
}
// Trick the compiler into thinking these variables do something.
breaker = 1;
smasher = 3 * breaker;
stomper = smasher + breaker;
breaker = stomper * smasher;
}
Another way to break it would be to put a function call (say, to printf) between the calls to myInput and myDisp.
It doesn't work, at least not consistently. Granted I have gcc 4.4.4 not 4.4.3
$ ./a.out
Entrer the numbers of elements you want:
5
2
Enter a number :Enter a number :4
Enter a number :1
Enter a number :2
Enter a number :3
2 4 1 134514562 3
Moral of the story is when you access uninitialized memory, anything can happen, including the appearance of working.
Since the two arrays are completely separate it really should not work. If it does it's just because they ended up in the same location in memory.
Probably it works because the memory location of the tab local to myInput e myDisp happens to be (almost?) the same.
It doesn't sound so weird to me: myInput and myDisp have almost the same signature (they differ for just one int parameter); even in the worst case scenario the locations on the stack referred by tab in the two functions would be still correctly aligned and shifted at most by two ints (i and cpt in myInput).
It appears the program is accessing the same memory location for every array int tab[n] you declared but, as mentioned, it should not work.
But I think what's happening here is something like: you are allocating tab[] inside main(), let's say, under the address 0x00000001 (take it as an example only). The array have n integers but no values at all.
Then you go into myInput(), declare the array again (same size), in other address, like 0x001F0000, and then set the values, one by one.
So, when the function terminates, it frees the allocated memory of its variables, so your array does not exist anymore.
But wait, this is C, so when you free the memory, you only tells the heap (or the memory allocator, in general) that the addresses can be used again. You do NOT exactly remove the values from memory.
Then you call myDisp() and declare your array again. It appears the memory you just requested has higher priority and then it is somewhat given again to your program. So your array is again instanciated and on the same address.
So, even if you did not fill it with values, the memory is read (as it is always valid in C) and the values are still there.
Oh, and the array declared inside main()? Nothing happens to that. Try to print its values and I bet you'll not have the correct ones.
That is my guess.
EDIT: Just to see things happening: try to declare another array after tab (do not rename tab), say tab2, same length, and use it to put your values instead of tab, then let the program run again :)

Resources