-1

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.

Christophe
  • 68,716
  • 7
  • 72
  • 138
  • 4
    *"double free or corruption (out)"* is certainly *not* a compilation error, it is a runtime error indicating that you are most likely freeing something that was already freed before. – Marco Bonelli Jan 14 '20 at 20:15
  • 1. Malloc and its mates do mot need a cast - See https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc 2. You should check the return value from `scanf`. 3. Not a good idea to have global variables – Ed Heal Jan 14 '20 at 20:18
  • You have only one malloc for `total_number_of_pages` and try to free many times within it. Don’t do that. One free per malloc. – Sami Kuhmonen Jan 14 '20 at 20:19
  • Altgernative after the free - set the pointer to null - as freeing a null is a noop – Ed Heal Jan 14 '20 at 20:29

1 Answers1

2

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)
Sami Kuhmonen
  • 30,146
  • 9
  • 61
  • 74
  • I think the code is correct because it is present by default at hackerrank and can not be edited. you may check it on hackerrank using the link given in the question. – Atul Suryvanshi Jan 15 '20 at 08:04
  • And, what about the second problem of **outputting the wrong value** (Problem has been described in the question). Please help me with that because that problem was much frustrating. – Atul Suryvanshi Jan 15 '20 at 08:08
  • @AtulSuryvanshi I don’t see any allocations in the code they provided. If you allocate differently than what they expected then you have to also free differently. Quite bad of them to provide deallocation without allocation, or am I seeing a different code – Sami Kuhmonen Jan 15 '20 at 08:13
  • 1
    @AtulSuryvanshi You also probably have negative indexes, if `I` goes to `count` and then you index by `count - i - 1` that’ll always be `-1` etc. Debug line by line and determine what’s wrong – Sami Kuhmonen Jan 15 '20 at 08:22