Search code examples
c++memory-leaksvalgrind

Possible leak from exception?


Why would valgrind say that this is possibly leaking.

#include <stdexcept>

int main(int argc, char const *argv[])
{
    throw std::runtime_error("");
    return 0;
}

With valgrind saying (updated with full check)

    ==26803== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==26803== Command: ./test
==26803== 
terminate called after throwing an instance of 'std::runtime_error'
  what():  
==26803== 
==26803== HEAP SUMMARY:
==26803==     in use at exit: 144 bytes in 1 blocks
==26803==   total heap usage: 2 allocs, 1 frees, 176 bytes allocated
==26803== 
==26803== 144 bytes in 1 blocks are possibly lost in loss record 1 of 1
==26803==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26803==    by 0x4E8FE42: __cxa_allocate_exception (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.20)
==26803==    by 0x400A07: main (in /home/arynaq/HioA/DAVE3605/oppgaver/uke910/test)
==26803== 
==26803== LEAK SUMMARY:
==26803==    definitely lost: 0 bytes in 0 blocks
==26803==    indirectly lost: 0 bytes in 0 blocks
==26803==      possibly lost: 144 bytes in 1 blocks
==26803==    still reachable: 0 bytes in 0 blocks
==26803==         suppressed: 0 bytes in 0 blocks
==26803== 
==26803== For counts of detected and suppressed errors, rerun with: -v
==26803== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
Aborted (core dumped)

What are these 144 bytes?


Solution

  • Constructor of std::runtime_error allocates some memory to keep it's internals, but destructor (which supposed to free it newer called) because of stack unwinding called terminate. These valgrind mechanics just force you to catch everything in main (good practice IMHO).

    int main() {
      try {
        /* all of your code goes here */
      } catch (std::exception& e) {
        std::err << "error: " << e.what() << std::endl;
        return 1;
      } catch(...) {
        std::err << "error: unknown exceptions" << std::endl;
        return 1;
      }
    }
    

    This approach allows you also catch some exceptions to trace them other way.