0

So I faced with an issues when I allocate some space, then I reallocate this space inside the recursive function and then I try to free this space outside of recursive function. Free() does not proceed any error, but as debugging shows I still have old content after free() is performed. Thus I am getting errors like: 1. malloc: * error for object 0x100200868: incorrect checksum for freed object - object was probably modified after being freed. OR 2.malloc: * error for object 0x100200000: pointer being freed was not allocated What can be the reason here?

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

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

    int i = 0;

    for(i = 0; i < 36; i++){

        if(intArr[i] == 1){
            buffer = calloc(6, sizeof(char)); //<<<--- have error here after realloc was done inside recursive function
            freeCh = buffer;
            if(i > 9){
                *freeCh = i - 10 + 'a' ;
            }else{
                *freeCh = i + '0';
            }

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

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

    if(temp -> isParent == 0){ //no superwords in this branch anymore
        temp -> list = getFinalList(temp -> list);
        fprintf(file, "<list> %s\n", *buffer);
        printList(temp -> list, file);
        fprintf(file, "\n<list>\n");
        return;
    }

    if(temp -> isWord){
        temp -> list = getFinalList(temp -> list);
        fprintf(file, "<list> %s\n", *buffer);
        printList(temp -> list, file);
        fprintf(file, "<list>\n");

    }


    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 + 10) * sizeof(char)); //<<--- realloc here
                if(buffer == NULL)
                    printf ("Realloc failed: %s\n", strerror(errno));
                bufferSize += 10;
            }
            freeCh++;
            recPrint(file, buffer, realBufferSize, bufferSize, freeCh, &temp -> children[i]);

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

enter image description here

jxh
  • 69,070
  • 8
  • 110
  • 193
YohanRoth
  • 3,153
  • 4
  • 31
  • 58
  • 4
    `free` doesn't affect the content of freed memory. It just adds it to the free list of the memory allocator. Your error message means that you're freeing the storage then using a pointer, which is now invalid because it points to freed storage, to modify that storage anyway. C gives you lots of rope to hang yourself in this fashion. – Gene Oct 18 '14 at 17:18
  • 1
    Why do you think `free` failed? – Deduplicator Oct 18 '14 at 17:18
  • `if(buffer == NULL)` --> `if(*buffer == NULL)` – BLUEPIXY Oct 18 '14 at 17:32

1 Answers1

3

In your program you pass into your program two pointers related to the memory you allocated. One is the address of your buffer pointer which you allocated. The other is a pointer into the buffer called freeCh.

In your recursive function, you latter reallocate onto *buffer. However, a reallocation may return a pointer different from the one that was originally allocated. When this happens, freeCh is no longer pointing to a valid memory location. And then, you code modifies the memory at freeCh, which is now freed memory.

Incidentally, when realloc() returns NULL, it has not freed the original pointer that you attempted to reallocate. So, you should not directly overwrite the pointer that you are reallocating with the return value of realloc(). You should use a temporary variable, and then test if realloc() returned a valid pointer. Assign this value to the pointer you reallocated only if realloc() succeeded.

jxh
  • 69,070
  • 8
  • 110
  • 193