Trying to solve this problem from Hackerrank. The problem itself is conceptually simple, basically finding the coordinates of a point by a simple arithmetic operation.
But the code requires us to print out multiple solutions after taking all the inputs, for which I am using a two-dimensional nx2 array. n is taken as the input from the user. Unfortunately, whenever n>=3, the hackerrank interface just does not give any output at all and I get wrong solutions. I tried to run the same code in my local IDE (CodeBlock for windows). There, when n>=3, the execution stops as the .exe file encounters some runtime error. So is it impossible to use a big matrix in those interfaces?
int main() {
unsigned int i=0, n;
scanf("%d", &n);
int **array=malloc(2*sizeof(int*));
for(;i<2;i++) *(array+i)=malloc(n*sizeof(int));
for(i=0;i<n;i++){/*Takes input via scanf*/
/* Calculate and store the result in **(array+i), *(*(array+i)+1))*/
}
for(i=0;i<n;i++) printf("%d %d\n", **(array+i), *(*(array+i)+1));
/*Prints the outputs. This is where the runtime error happens*/
return EXIT_SUCCESS;
}
Related
I am following the following function to calculate factorials of big numbers link, and I would like to understand a bit more why some things are happening...
#include<stdio.h>
#define MAX 10000
void factorialof(int);
void multiply(int);
int length = 0;
int fact[MAX];
int main(){
int num;
int i;
printf("Enter any integer number : ");
scanf("%d",&num);
fact[0]=1;
factorialof(num);
printf("Factorial is : ");
for(i=length;i>=0;i--){
printf("%d",fact[i]);
}
return 0;
}
void factorialof(int num){
int i;
for(i=2;i<=num;i++){
multiply(i);
}
}
void multiply(int num){
long i,r=0;
int arr[MAX];
for(i=0;i<=length;i++){
arr[i]=fact[i];
}
for(i=0;i<=length;i++){
fact[i] = (arr[i]*num + r)%10;
r = (arr[i]*num + r)/10;
//printf("%d ",r);
}
if(r!=0){
while(r!=0){
fact[i]=r%10;
r= r/10;
i++;
}
}
length = i-1;
}
My questions are:
What is the real meaning of the MAX constant? What does it mean if it's bigger or smaller?
I have found out that if I have a MAX = 10000 (as in the example), I can calculate up to 3250! If I try with 3251! I get a 'Abort trap: 6' message. Why is that number? Where does it come from?
Which would be the difference if I compile this code for a 32-bit machine with the flag -m32? Would it run he same as in 64-bit?
Thanks!
As Scott Hunter points out, MAX is the maximum number of elements in the fact and arr arrays, which means it's the maximum number of digits that can occur in the result before the program runs out of space.
Note that the code only uses MAX in its array declarations. Nowhere does it use MAX to determine whether or not it's trying to read from or write to memory beyond the end of those arrays. This is a Bad Thing™. Your "Abort trap: 6" error is almost certainly occurring because trying to compute 3251! is doing exactly that: using a too-large index with arr and fact.
To see the number of digits required for a given factorial, you can increase MAX (say, to 20,000) and replace the existing printf calls in main with something like this:
printf("Factorial requires %d digits.\n", length + 1);
Note that I use length + 1 because length isn't the number of digits by itself: rather, it's the index of the array position in fact that contains the most-significant digit of the result. If I try to compute 3251!, the output is:
Factorial requires 10008 digits.
This is eight digits more than you have available in fact with the default MAX value of 10,000. Once the program logic goes beyond the allocated space in the array, its behavior is undefined. You happen to be seeing the error "Abort trap: 6."
Interestingly, here's the output when I try to compute 3250!:
Factorial requires 10005 digits.
That's still too many for the program to behave reliably when MAX is set to 10,000, so the fact that your program calculates 3250! successfully might be surprising, but that's the nature of undefined behavior: maybe your program will produce the correct result, maybe it will crash, maybe it will become self-aware and launch its missiles against the targets in Russia (because it knows that the Russian counterattack will eliminate its enemies over here). Coding like this is not a good idea. If your program requires more space than it has available in order to complete the calculation, it should stop and display an appropriate error message rather than trying to continue what it's doing.
MAX is the number of elements in fact and arr; trying to access an element with an index >= MAX would be bad.
Error messages are often specific to the environment you are using, which you have provided no details for.
They are not the same, but the differences (for example, the size of pointers) should not affect this code in any discernible way.
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));
}
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)
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;
}
I'm currently learning to program in C. In one of the tasks in my assignment, I have to make a histogram (drawn by basic console output, like this: http://img703.imageshack.us/img703/448/histogram.jpg) to measure the number of characters in a text file (standard for this assignment is 1.3 MB). I did make a function like this:
int *yAxisAverageMethod(int average, int max, int min)
{
int *yAxis;
int i=0;
for (i=0;i<20;i++)
{
*(yAxis+i)=0;
}
/*
int length=sizeof(data)/sizeof(int);
*/
int lower_half_interval=average/10;
int upper_half_interval=(max-average)/10;
int current_y_value=min;
for (i=0;i<11;i++)
{
if (i==10){
*(yAxis+10)=average;
break;
}
*(yAxis+i)=current_y_value;
current_y_value+=lower_half_interval;
}
current_y_value+=average+upper_half_interval;
printf("Current y value:%d\n",current_y_value);
printf("Current max value:%d\n",max);
for (i=11;i<20;i++)
{
*(yAxis+i)=current_y_value;
current_y_value+=upper_half_interval;
}
return yAxis;
}
In this function, I intend to return an array of 20 integers, in order to make a y axis. I find the average of all characters, then used 20 lines of the console to display it. The lower 10 lines are used to display the lower than average values of the total amount of characters, and 10 lines are used to display the upper part. Each step in the y axis of the lower half is calculated by (average - min)/10, and each step in the y axis of the upper part is calculated by (max - average)/10. This is my method to draw the histogram, because I want to display the variants between values.
In the main method, I have this function call:
int *yAxis;
yAxis=yAxisAverageMethod(average,max,min);
I got a segmentation fault when I ran the function. In netbean GCC++ compiler, it works fine. Howerver, when I ran it on the university machines (which I have to compile it on command line and edit in Vi), I got the error. I guess it is because Netbean has its own memory manager? I don't understand.
Edited: I will ask about merge sort in anothe question.
*yAxis is a wild pointer. You never allocate memory for the int array you want to use.
int *yAxis = malloc(sizeof(int) * 20);
You are returning a pointer to nothing.
Where inside the function do you tell the computer to reserve some memory for *yAxis?
yAxis is a point, and you did not initialize it. it will point to unknown space what depends on the compiler. you should apply some memory for it firstly.
yAxis = malloc(sizeof(int)*20);
Don't forget to free() it in the caller.