Question

I have some linked lists in my code. Each linked list is a part of a large structure in a C code which is a local variable of a function. The code uses another function to populate the list, performs some other operations then calls a third function to print and delete it. First node needs not be deleted.

Problem: The function prints all of the data correctly, so there are no dangling pointers etc. But when I try to free the memory, I get heap corruption error. One sample of code which throws this error is:

flag = 0;

while( stpBS_current != NULL && stpFlags_current != NULL ){
// Linked list printing code is removed for clarity
    if( flag == 1 ){
        stpPrev = stpBS_current;
        stpFlags_prev = stpFlags_current;

        stpBS_current = (struct BasicService *)stpBS_current->pNext;
        stpFlags_current = (struct BasicService_Flags *)stpFlags_current->pNext;

        free( stpPrev );
        free( stpFlags_prev );
    }
    else
    {
        stpBS_current = (struct BasicService *)stpBS_current->pNext;
        stpFlags_current = (struct BasicService_Flags *)stpFlags_current->pNext;

        flag = 1;
    }
}

stpPrev and stpFlags_prev are local variables, stpBS_current and stpFlags_current are passed as argument in the print/delete function. The casting is performed because the original linked list has void *. As the same function prints all of the stored data correctly and this memory has not been freed elsewhere so I'm sure the pointers are correct.

I'm totally at a loss here. Everything on Google is about buffer overflows but I'm sure this is not the case. I'm using MS Visual C++ 2010 and the error it shows is:

Windows has triggered a breakpoint in ZTE Parser [24.04.2012].exe.

This may be due to a corruption of the heap, which indicates a bug in ZTE Parser [24.04.2012].exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while ZTE Parser [24.04.2012].exe has focus.

Of course I haven't pressed F12 so that's out of question. If I ignore the first error and continue code's execution then I get a couple of Assertion failures from same call to free() before it returns and eventually end up with:

MS VS 2010 Heap Corruption Snapshot

Are the void pointers culprit? But after all malloc() and free() use void pointer so IMO this shouldn't be a problem. I believe heap is a global memory so allocating and de-allocating in different functions shouldn't be a problem.

Code which allocates the memory is straightforward (2 linked lists). I have removed the head node initialization code for clarity:

stpBSC_current->pNext   =   malloc( sizeof(struct BasicServiceCode) );
stpFlags_current->pNext =   calloc( 1, sizeof(struct BasicServiceCode_Flags) );

if( stpBSC_current->pNext == NULL || stpFlags_current->pNext == NULL )
    exit( 1 );
else
{
    stpBSC_current      =   (struct BasicServiceCode *)stpBSC_current->pNext;
    stpFlags_current    =   (struct BasicServiceCode_Flags *)stpFlags_current->pNext;
}

I think if there were any loop holes in memory allocation or link list management then the errors should have come up while printing of the lists or at least some of the data must come out as garbage, but it works just perfectly. The error comes up when I try to free the memory. Any help and ideas will be highly appreciated. Thanks in advance.

Was it helpful?

Solution

Turns out that the flag condition was not correct (some printing code is not shown in the Question).

Cause: The free() was trying to free the head node which wasn't allocated using malloc(). It was a statically allocated variable. So this wasn't technically heap corruption as the initial error suggested, but as the assertion failure error specified, free() was attempting to free some memory located before the start of heap buffer, on the stack of course. This was causing the error.

@everyone Thanks for the help and suggestions.

OTHER TIPS

Just because you can print the data doesn't mean you didn't corrupt the heap. When you free the memory, the data stays there until the memory gets allocated again and overwritten. So your linked list could contain a pointer to freed memory, you can still read it, but encounter a problem later.

This is almost certainly caused by a buffer overflow: this causes your code to overwrite heap control information that may be stored immediately before and/or after the memory block you allocate. Such an error may go undetected until you try to free the memory.

Things to consider:

If you're parsing data (as the name of the program suggests), are you sure that the buffer that you copy the parsed input into is large enough?

Do the structs BasicServiceCode and BasicServiceCode_Flags contain any C-style strings? If so, you may very well be having a buffer overflow. Pay special attention to null terminators.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top