Why program is outputting right and wrong results for same condition - c

I have been solving a problem of the dynamic array on the hackerrank. The problem is of organizing books on shelves of a library. Here is the link to the question.
I have solved the problem on my computer and compile it successfully but when I try to compile it on the hackerrank platform it gives:
double free or corruption (out) error.
After compiling it on my computer when I run the program and pass the value it gives a different output for the same conditions, for example:-
here is code:-
#include <stdio.h>
#include <stdlib.h>
/*
* This stores the total number of books in each shelf.
*/
int* total_number_of_books;
/*
* This stores the total number of pages in each book of each shelf.
* The rows represent the shelves and the columns represent the books.
*/
int** total_number_of_pages;
int main()
{
int i, count = 0,len,*ptr;
int total_number_of_shelves;
scanf("%d", &total_number_of_shelves);
int total_number_of_queries;
scanf("%d", &total_number_of_queries);
len = sizeof(int *) * total_number_of_shelves + sizeof(int) * 1100 * total_number_of_shelves;
total_number_of_books = (int*)calloc(total_number_of_shelves , 4);
total_number_of_pages = (int**)malloc(len);
ptr = (int *)(total_number_of_pages+total_number_of_shelves);
for(i = 0; i < total_number_of_shelves; i++)
total_number_of_pages[i] = (ptr + 1100 * i);
while (total_number_of_queries--) {
int type_of_query;
scanf("%d", &type_of_query);
if (type_of_query == 1) {
int x, y;
scanf("%d %d", &x, &y);
total_number_of_books[x]+=1;
for (i = 0; i<1100; i++)
{
if(total_number_of_pages[x][i] != 0)
{
count++;
}
}
if(count == 1100)
{
printf("\nShelve is full\n");
}
else
{
for(i = 0; i < count; i++)
{
total_number_of_pages[x][count-i] = total_number_of_pages[x][count-1-i];
}
total_number_of_pages[x][count-i-1] = y;
}
} else if (type_of_query == 2) {
int x, y;
scanf("%d %d", &x, &y);
printf("%d\n", *(*(total_number_of_pages + x) + y));
} else {
int x;
scanf("%d", &x);
printf("%d\n", *(total_number_of_books + x));
}
}
if (total_number_of_books) {
free(total_number_of_books);
}
for (int i = 0; i < total_number_of_shelves; i++) {
if (*(total_number_of_pages + i)) {
free(*(total_number_of_pages + i));
}
}
if (total_number_of_pages) {
free(total_number_of_pages);
}
return 0;
}
Sample Input
5
5
1 0 15
1 0 20
1 2 78
2 2 0
3 0
Sample Output
78
2
In this program when I input 2 2 0 it should give result as 78 but it gives 0 as output. The problem becomes much confusing when I add a small code in the program at the given section i.e.
Code :- printf("\n%d\n",total_number_of_pages[x][count-i-1]); added in below given portition of code:
else
{
for(i = 0; i < count; i++)
{
total_number_of_pages[x][count-i] = total_number_of_pages[x][count-1-i];
}
total_number_of_pages[x][count-i-1] = y;
printf("\n%d\n",total_number_of_pages[x][count-i-1]); //this code is added extra to check the inputed value
}
after doing this it will print the value immedietly from the array after entering the value in the array for given position.
Above formated code prints the correct value of the given position of the array but when I try to print it using this portion of code it only returns 0 as the output.
Code:-
else if (type_of_query == 2) {
int x, y;
scanf("%d %d", &x, &y);
printf("%d\n", *(*(total_number_of_pages + x) + y));
If i try to give constant value in place of x and y in both code's then also the result will be same i.e correct value at first portition of code and 0 at above code even though there is no change in the logic of printing the value.
Please help me to solve these two problems:-
1. Wrong output value.
2. Compilation error double free or corruption (out) at hackerrank platform for same code.

One obvious error is here:
total_number_of_pages = (int**)malloc(len);
...
for (int i = 0; i < total_number_of_shelves; i++) {
if (*(total_number_of_pages + i)) {
free(*(total_number_of_pages + i));
}
}
You allocate one memory block and then you try to free pointers in the middle of the block. This will cause problems. You only need to free once for one allocation. So:
free(total_number_of_pages)

Related

C fibonacci and equation problem with my code

Hello im new to C programming and this is my C Quiz question.
I tried really hard but i cant find the solution or whats wrong with my code.
This equation block cant work.
Any help will be appreciated
Write a C program that displays the below menu and performs the
corresponding operation, according to the selected menu item.
Write separate functions for each menu item and call the related function according to the
selection.
The menu:
(1) Calculate fibonacci value of the entered number,
(2) Calculate the equation (Get value of R from the user),
(3) Get four numbers from the user, sort them in ascending order
Enter your choice:
When the user enters a number (1, 2 or 3) corresponding function will be called
to perform the operation.
The user will enter -1 if he wants to continue and the
menu will be appeared on the screen again.
Question Equation Pic
#include <stdio.h>
#include <stdlib.h>
int fibonacci(int numForFibonacci)
{
int i = 0;
int j = 1;
int k = 1;
for (int b = 1; b <= numForFibonacci; b++)
{
k = i + j;
printf("%d \n", i);
i = j;
j = k;
printf("%d ", k);
}
printf("\n");
return k;
}
float theEquation(float numR)
{
float multipl, result = 1;
for (int i = 1; i <= numR; i++)
{
multipl = (2i + 4) / (i * i);
result *= multipl;
}
printf("Result is %f", result);
return result;
}
int ascending(int n)
{
int k = 0, i = 0, j = 0, number[4];
for (int w = 0; w < n; w++)
scanf("%d", &number[w]);
for (i = 0; i < n; ++i)
{
for (j = i + 1; j < n; ++j)
{
if (number[i] > number[j])
{
k = number[i];
number[i] = number[j];
number[j] = k;
}
}
}
for (i = 0; i < n; ++i)
printf("\n%d \n", number[i]);
return i;
}
int main()
{
int choice, choiceFibo;
float choiceR;
do
{
printf("[1]Fibonacci calculation\n");
printf("[2]calculating the equation: (2k+4)/(k*k)\n");
printf("[3]sorting numbers in ascending order\n");
scanf("%d", &choice);
if (choice == 1)
{
printf("enter a number for fibonacci\n ");
scanf("%d", &choiceFibo);
fibonacci(choiceFibo);
}
else if (choice == 2)
{
printf("[2]enter a number for (2k+4)/(k*k)\n");
scanf("%f", &choiceR);
theEquation(choiceR);
}
else
{
printf("[3]enter four numbers to sort them in ascending order\n");
ascending(4);
}
printf("If you want to do another calculation enter '-1'.\n");
scanf("%d", &choice);
} while (choice == -1);
return 0;
}
TL;DR: Two main issues:
<integer>i in GNU C represents a complex number, not multiplication.
integer division is not what you'd expect
Your issue lies on this line:
multipl = (2i + 4) / (i * i);
You might think that 2i would evaulate as 2 * i, but in C, 2i is a complex int.
This can be seen here:
#include <stdio.h>
int main()
{
int i=1;
printf("%d", 2i);
return 0;
}
You would expect this to print 2, but instead we get a warning.
Compiled with onlinegdb:
warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘complex int’
Second issue: Integer division. The other answer already covered it pretty well, but for the sake of self-contained answers:
In C, integer division finds the integer solution and discards the remainder.
2/5 = 0
6/5 = 1
10/5 = 2
10/4 = 2
10.0 / 4 = 2.5
(double)10/4 = 2.5
You need to "type coerce" one of the values in your numerator or denominator to a float/double, which will coerce the entire fraction to a float/double.
You can do this either with 2.0*i or (double)2*i. Either one works, but the second one is more explicit for readability.
To fix the issue, simply change 2i to (double)2*i.
There are only three edits required to get a clean compile:
Change int main() to int main(void)
Change (2i + 4) / (i * i) to (2*i + 4) / (i * i)
Change int ... number[4]; to int ... number[4]={0};
If you did not see something similar to the following upon your compile, then turn on all warnings:
> s0_15.c - 4 warnings
> 28, 28 warning: implicit conversion discards imaginary component: '_Complex int' to 'float'
> 45, 17 warning: variable 'number[i]' may be uninitialized when used here
> 38, 5 note: variable 'number' is declared here
> 54, 27 warning: variable 'number[i]' may be uninitialized when used here
> 38, 5 note: variable 'number' is declared here
> 58, 5 warning: function declaration isn't a prototype.
To ensure accurate calculations, see integer division addressed in another answer under your post.

Find minimum number of wires to connect the bulbs code

I have written this C code to find a minimum number of wires required to switch on all the bulbs.
The problem is that there is x number of computers, some of which are On and some are Off and the distance between these bulb from the first bulb is given. The computer can be switched ON by connecting it to its nearby ON the bulb.
So the inputs are as follows:
X = 6 (number of bulbs)
1 0 1 1 0 1(1 means the bulb is ON and 0 means the bulb is OFF)
2 4 8 36 37 40 (distance between one bulb from the first bulb)
and the output will be:
3 (Reason: 4 - 2 = 2, 37 - 36 = 1, 2 + 1 = 3)
#include <stdio.h>
int main(){
int n,pre,post,sum = 0;
scanf("%d",&n);
int arr[n],dist[n];
for(int i =0;i<n;i++){
scanf("%d ",&arr[i]);
}
for(int i =0;i<n;i++){
scanf("%d ",&dist[i]);
}
for(int i =0;i<6;i++){
if(arr[i] == 0){
pre = dist[i]-dist[i-1];
post = dist[i+1]-dist[i];
if(pre>post){
sum +=post;
}
else{
sum+=pre;
}
}
}
printf("\n %d",sum);
}
It keeps on taking the inputs. Please tell me what is the error in this code?
Thanks in advance.
Edited: I missed that scanf("%d",n) by mistake. It was there in my original code and the problem still persists.
As Sandrin mentioned, n is not defined.
Assuming your input file is:
6
1 0 1 1 0 1
2 4 8 36 37 40
You need to add code to set n:
scanf("%d ",&n);
And, you need to insert this before the definitions of your matrix
Here's the refactored code:
#include <stdio.h>
int
main(void)
{
int n, pre, post, sum = 0;
#if 1
scanf("%d ",&n);
#endif
int arr[n], dist[n];
for (int i = 0; i < n; i++)
scanf("%d ", &arr[i]);
for (int i = 0; i < n; i++)
scanf("%d ", &dist[i]);
for (int i = 0; i < 6; i++) {
if (arr[i] == 0) {
pre = dist[i] - dist[i - 1];
post = dist[i + 1] - dist[i];
if (pre > post) {
sum += post;
}
else {
sum += pre;
}
}
}
printf("\n %d", sum);
return 0;
}
Putting a side technical errors (e.g. n not initialized), the algorithms assumes that all problems can be solved by single pass. This is not true for cases like:
1 0 0 0 0 1
0 1 3 4 6 7
Where the code will choose to connect bulbs [0,1], [2,3], and [4,5], based on pre/post distances. However, bulbs 2 and 3 will remain disconnected.
A better algorithm will attempt to find, for each sequence of off bulbs, which is the most expensive connection, and avoid it.
I have come up with this solution for my code and I have tried to consider all the test cases. If you find any test case that won't run feel free to tell.
#include <stdio.h>
#include <stdlib.h>
int main(int ac, char **av){
int n,pre,post,sum = 0;
scanf("%d",&n);
int *input,*distance;
input = malloc(n * sizeof(int));
for (int i=0; i < n; i++)
{
scanf("%d", &input[i]);
}
distance = malloc(n * sizeof(int));
for (int i=0; i < n; i++)
{
scanf("%d", &distance[i]);
}
for(int i =0;i<6;i++){
if(input[i] == 0){
pre = distance[i]-distance[i-1];
if(input[i+1]==1){
post = distance[i+1]-distance[i];
input[i] =1;
if(pre>post){
sum +=post;
}
else{
sum+=pre;
}
}
else{
sum = sum+pre;
}
printf("%d.....%d....%d\n",pre,post,sum); //Debugging
}
}
printf("\n %d",sum);
free(input);
free(distance);
}

Need to generate 4 random numbers without repetition in C programming. 1 to 4

I want to generate numbers 1 to 4 in a random fashion using C programming.
I have made provision to print a[0] directly in a while loop and for any further element the program checks whether the new number from a[1] to a[3] is same as any of the previous elements. A function has been created for the same. int checkarray(int *x, int y).
The function checks current element with previous elements one by one by reducing the passed address. If it matches the value it exits the loop by assigning value zero to the condition variable (int apply).
return apply;
In the main program it matches with the int check if check==1, the number is printed or else the loop is repeated.
Problem faced: The number of random numbers generated is varying between 2 and 4.
e.g
2 4
2 4 3
1 3 3 4
etc
Also repetition is there sometimes.
#include <stdio.h>
#include <conio.h>
int checkarray(int *x, int y);
void main() {
int a[4], i = 0, check;
srand(time(0));
while (i < 4) {
a[i] = rand() % 4 + 1;
if (i == 0) {
printf("%d ", a[i]);
i++;
continue;
} else {
check = checkarray(&a[i], i);
}
if (check == 1) {
printf("\n%d ", a[i]);
} else {
continue;
}
i++;
}
getch();
}
int checkarray(int *x, int y) {
int arrcnt = y, apply = 1, r = 1;
while (arrcnt > 0) {
if (*x == *(x - 2 * r)) {
apply = 0;
exit(0);
} else {
arrcnt--;
r++;
continue;
}
}
return apply;
}
Let's look at the checkarray function, which is supposed to check if a number is already present in the array.
It is called this way:
check = checkarray(&a[i], i);
Where a is an array of 4 integers and i is the actual index, so it tries to scan the array backwards looking for any occurrences of a[i]
int checkarray(int *x,int y)
{
int arrcnt=y,apply=1,r=1;
while(arrcnt>0)
{
if(*x==*(x-2*r))
// ^^^ Why? This will cause an out of bounds access.
{
apply = 0;
exit(0); // <-- This ends the program. It should be a 'break;'
}
else
{
arrcnt--;
r++;
continue;
}
}
return apply;
}
Without changing the interface (which is error prone, in my opinion) it could be rewritten as
int check_array(int *x, int y)
{
while ( y )
{
if ( *x == *(x - y) )
return 0;
--y;
}
return 1;
}
Testable here.
There are many other issues which should be addressed, though, so please, take a look to these Q&A too.
Does "n * (rand() / RAND_MAX)" make a skewed random number distribution?
Why do people say there is modulo bias when using a random number generator?
Fisher Yates shuffling algorithm in C
int main() vs void main() in C
Why can't I find <conio.h> on Linux?
Your approach is tedious but can be made to work:
there is no need to special case the first number, just make checkarray() return not found for an empty array.
you should pass different arguments to checkarray(): a pointer to the array, the number of entries to check and the value to search.
you should not use exit(0) to return 0 from checkarray(): it causes the program to terminate immediately.
Here is a modified version:
#include <stdio.h>
#include <conio.h>
int checkarray(int *array, int len, int value) {
int i;
for (i = 0; i < len; i++) {
if (array[i] == value)
return 0;
}
return 1;
}
int main() {
int a[4], i = 0, value;
srand(time(0));
while (i < 4) {
value = rand() % 4 + 1;
if (checkarray(a, i, value)) {
printf("%d ", value);
a[i++] = value;
}
}
printf("\n");
getch();
return 0;
}

How do I print out 100 numbers in an array then add them using C

I'm trying to print out 100 numbers from an array using a loop and then add them all together. So far I have:
#include <stdio.h>
#include <stdlib.h>
int main(){
int* number = malloc(101 * sizeof(int));
int num = 0;
number[num] = 1;
while (number[num] <= 100){
printf(" %d\n ", number[num]);
num = num +1;
number[num] = number[num]+1;
}
return 0;
}
but this just prints 1 once.
number[num] = number[num]+1;
You only properly set number[0]. Now you are trying to take whats in number[1] and add to it, in the first iteration. You didn't set it to anything though, leaving it uninitialised. This is undefined behaviour. What you most likely wanted to do is
number[num] = number[num-1]+1;
To add one to the previous number before after printing it. Now it will print fine.
To add them up, simply do
for (int a = 0; a < 100; a++) {
number[100] += number[a]; // add number[a] to result
}
printf("%d\n",number[100]);
Also, don't forget to free your dynamically allocated array at the end.
Try this:
#include <stdio.h>
int main () {
int n[ 100 ]; /* n is an array of 100 integers */
int i,j;
int sum = 0;
/* initialization */
for ( i = 0; i < 100; i++ ) {
n[ i ] = i + 100; /* set element at location i to i + 100 */
}
/* output each array element's value */
for (j = 0; j < 100; j++ ) {
printf("Element[%d] = %d\n", j, n[j]);
sum += n[j];
}
printf("Sum of Elements = %d\n", sum);
return 0;
}
Remember that you should declare an array, then initialize it, print it out and after all print out the sum
You can just print out 1 to 100, then you could quickly use some maths to get the count of all numbers added together, for example, one of Gauss' algorithms, specifically http://betterexplained.com/articles/techniques-for-adding-the-numbers-1-to-100/
There’s a popular story that Gauss, mathematician extraordinaire, had a lazy teacher. The so-called educator wanted to keep the kids busy so he could take a nap; he asked the class to add the numbers 1 to 100.
Here's what I would do: -
int i = 0;
for (i = 1; i <= 100; i++) {
printf("%d", i);
}
// gauss technique 100(100 + 1) / 2
int count = (100 * 100 + 100 * 1) / 2;
printf("all numbers added: %d", count);

Weird Output with first case integer

Here are two functions below that compile perfectly but I seem to be getting a weird error with the very first inputted integer. I have tried debugging in GDB but when it's only the first inputted value that is having this weird error, then it makes things complicated.
#include <stdio.h>
#include "Assg9.h"
#include <stdlib.h>
#include <assert.h>
#include <math.h>
void getPrimes(int usernum, int* count, int** array){
(*count) = (usernum - 1);
int sieve[usernum-1], primenums = 0, index, fillnum, multiple;
for(index = 0, fillnum = 2; fillnum <= usernum; index++, fillnum++){
sieve[index] = fillnum;
}
for (; primenums < sqrt(usernum); primenums++)
{
if (sieve[primenums] != 0){
for (multiple = primenums + (sieve[primenums]); multiple < usernum - 1; multiple += sieve[primenums])//If it is not crossed out it starts deleting its multiples.
{
if(sieve[multiple]) {
--(*count);
sieve[multiple] = 0;
}
}
}
}
int k;
for (k = 0; k < usernum; k++)
if (sieve[k] != 0)
{
printf("%d ", sieve[k]);
}
*array = malloc(sizeof(int) * (usernum +1));
assert(array);
(*array) = sieve;
}
void writeToOutputFile(FILE *fpout, const int *array, int n, int count){
int i;
fprintf(fpout, "There are %d prime numbers less than or equal to %d \n", count, n);
for(i = 0; i < count; i++)
{
if(*(array + i) != 0){
fprintf(fpout, "%d ", *(array + i));
}
}
}
Our Output:
Please enter an integer in the range 2 <-> 2000 both inclusive: 2
2 32664
Do you want to try again? Press Y for Yes and N for No: y
Please enter an integer in the range 2 <-> 2000 both inclusive: 2
2
Do you want to try again? Press Y for Yes and N for No: n
Good bye. Have a nice day
Expected output should obviously just display 2. This is the case for any integer from 2-2000 for the very first inputted integer. The very last, or last 2, prime numbers print very large numbers, sometimes even negative numbers. I have no clue why, but after the first inputted value everything works perfectly. Tried debugging this with GDB like crazy but with no luck. Would really appreciate someone's help for this bizarre error
You aren't initializing the sieves array to 0s. So you're looping from 0 to usernum-1, printing out every number that isn't a 0. Since you didn't initialize the array, the 2nd element is a random value and is being printed out
This code is a problem:
(*array) = sieve;
You are are assigning the address of sieve, a temporary local array, to *array. You need to copy the array contents instead.
Are you also this person who has asked three questions about identical code?

Resources