Search code examples
c++valgrind

Valgrind false memory leak for a pointer stored in a static std::list


Valgrind shows a memory leak for a pointer stored in static std::list variable. below is the sample code.

Leak shown for "auto t = new Abc;" ( definitely lost: 4 bytes in 1 blocks)

Is this a BUG in Valgrind ?

Is there a solution/workaround (other than clearing the Pool::queue manually) ?

 #include <list>

struct Abc
{
    int y = 9;
};

struct Pool
{
    static std::list<Abc*> queue;

    ~Pool()
    {
        for (auto p : queue)
        {
            delete p;
        }       
    }
};

std::list<Abc*> Pool::queue;

int main () 
{
  
  auto t = new Abc; //<<<<<<<<<<< Leak shown for this
  Pool::queue.push_back(t);

  return 0;
}

Valgrind output

g++ -ggdb Main.cpp

valgrind --leak-check=full ./a.out

==8807== Memcheck, a memory error detector
==8807== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8807== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==8807== Command: ./a.out
==8807== 
==8807== 
==8807== HEAP SUMMARY:
==8807==     in use at exit: 4 bytes in 1 blocks
==8807==   total heap usage: 3 allocs, 2 frees, 72,732 bytes allocated
==8807== 
==8807== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==8807==    at 0x4C2A1E3: operator new(unsigned long) (vg_replace_malloc.c:334)
==8807==    by 0x4007D9: main (Main.cpp:26)
==8807== 
==8807== LEAK SUMMARY:
==8807==    definitely lost: 4 bytes in 1 blocks
==8807==    indirectly lost: 0 bytes in 0 blocks
==8807==      possibly lost: 0 bytes in 0 blocks
==8807==    still reachable: 0 bytes in 0 blocks
==8807==         suppressed: 0 bytes in 0 blocks
==8807== 
==8807== For counts of detected and suppressed errors, rerun with: -v
==8807== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Solution

  • The std::list destructs (the compiler takes care of that for a static object), the objects in it don't as that's the job of ~Pool, which the code doesn't invoke anywhere. The Abc instance survives and is indeed not reachable, the leak report is correct.