Consider the following program
#include <iostream>
#include <cstring>
#include <stdexcept>
class cmdline {
char *stored_file = nullptr;
public:
cmdline(const int argc, char const* const* argv) :
stored_file(argc < 6 ? throw std::logic_error("Not enough parameters") : new char[std::strlen(argv[1]) + 1]) { }
~cmdline() { delete[] stored_file; }
};
int main(int argc, char *argv[])
{
using namespace std;
cmdline *p;
try {
p = new cmdline(argc, argv);
}
catch(const logic_error& err) {
cout << err.what() << endl;
exit(1);
}
return 0;
}
In the constructor of cmdline
, an exception is thrown if the condition argc < 6
is realized. In this case I would have expected that no memory is allocated by the constructor.
When I run with valgrind --leak-check=full
I get the errors:
==9845==
==9845== HEAP SUMMARY:
==9845== in use at exit: 190 bytes in 2 blocks
==9845== total heap usage: 5 allocs, 3 frees, 73,926 bytes allocated
==9845==
==9845== 46 bytes in 1 blocks are possibly lost in loss record 1 of 2
==9845== at 0x4841F11: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9845== by 0x4966049: allocate (new_allocator.h:137)
==9845== by 0x4966049: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) [clone .isra.0] (cow_string.h:3537)
==9845== by 0x4966116: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) [clone .part.0] [clone .isra.0] (cow_string.h:3096)
==9845== by 0x49664F7: std::logic_error::logic_error(char const*) (cow-stdexcept.cc:87)
==9845== by 0x1093B9: cmdline::cmdline(int, char const* const*, int) (test.cpp:11)
==9845== by 0x109267: main (test.cpp:22)
==9845==
==9845== 144 bytes in 1 blocks are possibly lost in loss record 2 of 2
==9845== at 0x48417AB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9845== by 0x493BB44: __cxa_allocate_exception (eh_alloc.cc:284)
==9845== by 0x1093A4: cmdline::cmdline(int, char const* const*, int) (test.cpp:11)
==9845== by 0x109267: main (test.cpp:22)
==9845==
==9845== LEAK SUMMARY:
==9845== definitely lost: 0 bytes in 0 blocks
==9845== indirectly lost: 0 bytes in 0 blocks
==9845== possibly lost: 190 bytes in 2 blocks
==9845== still reachable: 0 bytes in 0 blocks
==9845== of which reachable via heuristic:
==9845== stdstring : 46 bytes in 1 blocks
==9845== suppressed: 0 bytes in 0 blocks
==9845==
==9845== For lists of detected and suppressed errors, rerun with: -s
==9845== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Needless to say, test.cpp:11 is the line where stored_file is initialized.
What exactly is the origin of the leak?