Search code examples
c++linuxmemory-leaksvalgrind

C++ memory leak. Valgrind - mismatched delete


I receive objects from Thread #1 - its a 3rd party lib code - my callback called on it.

Objects have fixed-length string fields wrapped:

typedef struct somestr_t {
    char * Data;
    int    Len; } somestr_t;

I have to create copy of the objects by hand every time, before I can pass it further to my code. So amongst other things I copy these strings too using this helper:

inline void CopyStr(somestr_t * dest, somestr_t * src)
{
    if (src->Len == 0) {
        dest->Len = 0;
        return;
    }

    char* data = new char[src->Len];

    memcpy(data, src->Data, src->Len);

    dest->Data = data;
    dest->Len = src->Len;
}

Then somewhere down the road I delete the object and its string fields:

if (someobj != nullptr)
{
    if (someobj ->somestr.Len != 0) delete someobj ->somestr.Data;
    . . .
    delete someobj ;
}

When I run valgrind I get these in places where I would expect the strings to be deleted:

==33332== Mismatched free() / delete / delete []
==33332==    at 0x48478DD: operator delete(void*, unsigned long) (vg_replace_malloc.c:935)
==33332==    by 0x41B517: cleanup() (Recorder.cpp:86)
==33332==    by 0x41BB29: signal_callback(int) (Recorder.cpp:129)
==33332==    by 0x4C11DAF: ??? (in /usr/lib64/libc.so.6)
==33332==    by 0x4CD14D4: clock_nanosleep@@GLIBC_2.17 (clock_nanosleep.c:48)
==33332==    by 0x4CD6086: nanosleep (nanosleep.c:25)
==33332==    by 0x4D02DE8: usleep (usleep.c:32)
==33332==    by 0x41C3EF: Logger(void*) (LogThreads.h:28)
==33332==    by 0x4C5C6C9: start_thread (pthread_create.c:443)
==33332==    by 0x4BFC2B3: clone (clone.S:100)
==33332==  Address 0xd661260 is 0 bytes inside a block of size 12 alloc'd
==33332==    at 0x484622F: operator new[](unsigned long) (vg_replace_malloc.c:640)
==33332==    by 0x419E72: CopyStr (CbOverrides.h:23)

and summary report:

==34077== HEAP SUMMARY:
==34077==     in use at exit: 328,520 bytes in 3,828 blocks
==34077==   total heap usage: 124,774 allocs, 120,946 frees, 559,945,294 bytes allocated
==34077==
==34077== LEAK SUMMARY:
==34077==    definitely lost: 0 bytes in 0 blocks
==34077==    indirectly lost: 0 bytes in 0 blocks
==34077==      possibly lost: 0 bytes in 0 blocks
==34077==    still reachable: 328,520 bytes in 3,828 blocks
==34077==         suppressed: 0 bytes in 0 blocks

I never used valgrind (or any c++ tool) before so I am not sure - why mismatch delete is reported? why there are 328K unreleased memory on exit?


Solution

  •     char* data = new char[src->Len];
    

    and

        if (someobj ->somestr.Len != 0) delete someobj ->somestr.Data;
    

    That delete should be delete [].

    Why are there still reachable: 425,333 bytes in 3,860 blocks. Sorry, my crystal ball isn't working.

    Normally Valgrind does give a hint as to what you need to do

    ==19283== Rerun with --leak-check=full to see details of leaked memory
    

    It's a little bit mean in that after you've done that it will tell you about another option

    ==21816== Reachable blocks (those to which a pointer was found) are not shown.
    ==21816== To see them, rerun with: --leak-check=full --show-leak-kinds=all
    

    Try those and start working through the non-freed memory.