Search code examples
cmallocdynamic-memory-allocationrealloccalloc

How to free reallocated and callocated memory?


How to free the memory which has been once callocated in the beggining, then reallocated and callocated right after? This ptr was my attempt but valgrind says that there has been 6 allocs and 6 frees, yet there are 90 bytes in 3 blocks definitely lost.

char *textInFile = (char *) calloc(currentLength + 1, sizeof(char) * currentLength);
char *currentLine = (char *) calloc(currentLength + 1, sizeof(char) * currentLineLength);
...
while ((textInFile[index] = getc(f)) != EOF) {
    if (index > currentLength - 3) {
        currentLength += 10;
        ptr = textInFile;
        textInFile = (char *) realloc(textInFile, currentLength);
        textInFile = (char *) calloc(currentLength, sizeof(char) * currentLength);
        free(ptr);
    }
    ...
    if (textInFile[index] == '\n') {
        int k = 0;
        for (int i = previousIndex; i < index; i++) {
            if (k > currentLineLength - 3) {
                currentLineLength += 10;
                ptr = currentLine;  
                currentLine = (char *) realloc(currentLine, currentLineLength);
                currentLine = (char *) calloc(currentLineLength, sizeof(char) * currentLineLength);
                free(ptr);
            }
    ...
    index++;
}
...
free(textInFile);
free(currentLine);

==4426== HEAP SUMMARY:

==4426== in use at exit: 90 bytes in 3 blocks

==4426== total heap usage: 9 allocs, 9 frees, 14,668 bytes allocated

==4426==

==4426== LEAK SUMMARY:

==4426== definitely lost: 90 bytes in 3 blocks

==4426== indirectly lost: 0 bytes in 0 blocks

==4426== possibly lost: 0 bytes in 0 blocks

==4426== still reachable: 0 bytes in 0 blocks

==4426== suppressed: 0 bytes in 0 blocks


Solution

  • You need to call free() on every non-NULL pointer that was returned by calloc(). If you call realloc(), then you shouldn't call free() on the pointer that you passed in as an argument to realloc(), but you should call free() on the pointer that realloc() returned. (Note: using realloc() correctly is tricky, especially if you want to handle errors correctly -- I recommend avoiding it unless it's strictly necessary)

    One problem in particular with your code is this:

    textInFile = (char *) realloc(textInFile, currentLength);
    textInFile = (char *) calloc(currentLength, sizeof(char) * currentLength);
    

    In the second line you overwrite textInFile's pointer with the pointer returned by calloc(), thus losing any access to the old value that was returned by realloc(), so you have no way to free that buffer; hence you have a memory leak.