Search code examples
crealloc

Cannot free data of a buffer after it was reallocated inside recursive function. What can be the reason?


So I faced with an issue - when I have data that exceeds initial size of my buffer and I do reallocation inside recursive function then I get an error for freeing its buffer.

*malloc: *** error for object 0x100106da0: pointer being freed was not allocated*

Here is the code:

void recPrint(FILE *file, char *buffer, int realBufferSize, int bufferSize, char *freeCh, NodePtr* temp){

   //some code here...

    int *intArr = temp -> usedIndices;
    int i = 0;
    for(i = 0; i < 36; i++){
        if(intArr[i] == 1){
            if(i > 9){
                *freeCh = i - 10 + 'a' ;
            }else{
                *freeCh = i + '0';
            }
            realBufferSize++;
            if (realBufferSize >= bufferSize){
                buffer = realloc(buffer, (bufferSize + 100) * sizeof(char)); // <<--- REALLOC here
                bufferSize += 100;
            }
            freeCh++;
            recPrint(file, buffer, realBufferSize, bufferSize, freeCh, &temp -> children[i]);

            //now we need to remove all extra characters till the next turn
            freeCh--;
            *freeCh = '\0';
        }
    }

}

void printTrie(FILE *file, char *initialPath){

    initPath = initialPath;
    if(root.isParent == 0) return;
    char *buffer;
    char *freeCh;
    int *intArr = root.usedIndices;
    int bufferSize = 10;
    int realBufferSize = 1000;

    int i = 0;

    for(i = 0; i < 36; i++){
        buffer = calloc(1001, sizeof(char));
        freeCh = buffer;

        if(intArr[i] == 1){
            if(i > 9){
                *freeCh = i - 10 + 'a' ;
            }else{
                *freeCh = i + '0';
            }

        freeCh++;
        realBufferSize++;
        recPrint(file, buffer, realBufferSize, bufferSize, freeCh, &root.children[i]);
        free(buffer); //<<--- getting error here
        }
    }
}

Solution

  • The comment from @WhozCraig points out the problem. Here's a suggested fix.

    1. Return the realloced buffer from recPrint.

    2. Use free on the returned value of recPrint.

    char* recPrint(FILE *file, char *buffer, int realBufferSize,
                   int bufferSize, char *freeCh, NodePtr* temp){
    
       ....
    
       // where you recurse...
       buffer = recPrint(file, buffer, realBufferSize, 
                         bufferSize, freeCh, &temp -> children[i]);
    
       // and always return the *current* buffer pointer back to the caller.
       return buffer;
    }
    

    In printTrie:

        buffer = recPrint(file, buffer, realBufferSize, bufferSize, freeCh, &root.children[i]);
        free(buffer);