0

I cannot understand what is happening in the following code:

template<typename X>
class TestClass {
public:
    void alloc(X x) {
    }
};

template<>
void TestClass<int>::alloc(int x) {
    char* buf = new char[1];
    delete[] buf;
}

int main() {
    return 0;
}

So main does not declare and does not instantiate the TestClass. TestClass is only defined with a template, and a template specialization definition for int. The alloc method does the new, but the method is never called. However, if I run with valgrind, I get this:

==62783== HEAP SUMMARY:
==62783==     in use at exit: 72,704 bytes in 1 blocks
==62783==   total heap usage: 1 allocs, 0 frees, 72,704 bytes allocated
==62783== 
==62783== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==62783==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==62783==    by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==62783==    by 0x40106C9: call_init.part.0 (dl-init.c:72)
==62783==    by 0x40107DA: call_init (dl-init.c:30)
==62783==    by 0x40107DA: _dl_init (dl-init.c:120)
==62783==    by 0x4000C69: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==62783== 
==62783== LEAK SUMMARY:
==62783==    definitely lost: 0 bytes in 0 blocks
==62783==    indirectly lost: 0 bytes in 0 blocks
==62783==      possibly lost: 0 bytes in 0 blocks
==62783==    still reachable: 72,704 bytes in 1 blocks
==62783==         suppressed: 0 bytes in 0 blocks
==62783== 
==62783== For counts of detected and suppressed errors, rerun with: -v
==62783== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

If you comment out the buf = new line, you will get:

==64665== HEAP SUMMARY:
==64665==     in use at exit: 0 bytes in 0 blocks
==64665==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==64665== 
==64665== All heap blocks were freed -- no leaks are possible

So, why is memory allocated but never freed if that code is not executed? This is a strip down example from a more complex code where I encountered this situation, and I could not figure out the reason. Don't ask why I did this, it's not relevant, I know I can rewrite the code to avoid this, the question is why is this happening? Is this a compiler bug?

Thanks, Victor

  • could you provide compiler version? – MarcinG Nov 18 '19 at 13:26
  • 1
    There's no leak in that code. All the lost categories are zero. – Shawn Nov 18 '19 at 13:26
  • sure, gcc version: ```gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12)``` – Victor Olaru Nov 18 '19 at 13:29
  • 2
    Related or duplicated of: https://stackoverflow.com/questions/30376601/valgrind-memory-still-reachable-with-trivial-program-using-iostream – Davide Spataro Nov 18 '19 at 13:29
  • Also, can't duplicate your results. I get `total heap usage: 1 allocs, 1 frees, 72,704 bytes allocated`. – Shawn Nov 18 '19 at 13:30
  • that's great @Shawn, can you provide the gcc and valgrind version? maybe I need to update, and would be useful to know the version where this does not reproduce, thanks – Victor Olaru Nov 18 '19 at 13:34
  • I upgraded valgring to 3.15.0 and now I got the same result: ```total heap usage: 1 allocs, 1 frees, 72,704 bytes allocated```, however, when commenting out the code that shouldn't run, I get: ```total heap usage: 0 allocs, 0 frees, 0 bytes allocated```, so why the difference? – Victor Olaru Nov 18 '19 at 14:13

0 Answers0