I am new to the smart pointers world. I've done my reading and all of them stated that smart pointers will avoid leaking memory even when the program will exit after encountering an exception.
I wrote down a simple program to try this out, but Valgrind is telling me my program is leaking memory (three allocs and only one free).
This is the source code:
#include <iostream>
#include <memory>
using namespace std;
int main()
{
auto_ptr<int> ptr_int(new int(5));
throw std::bad_alloc();
cout << *ptr_int;
}
And this Valgrind report:
==27862== Memcheck, a memory error detector
==27862== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==27862== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==27862== Command: ./smart_pointers
==27862== Parent PID: 5388
==27862==
==27862==
==27862== HEAP SUMMARY:
==27862== in use at exit: 104 bytes in 2 blocks
==27862== total heap usage: 3 allocs, 1 frees, 120 bytes allocated
==27862==
==27862== 4 bytes in 1 blocks are still reachable in loss record 1 of 2
==27862== at 0x4026351: operator new(unsigned int) (vg_replace_malloc.c:255)
==27862== by 0x804878A: main (smart_pointers.cpp:8)
==27862==
==27862== 100 bytes in 1 blocks are possibly lost in loss record 2 of 2
==27862== at 0x4025BD3: malloc (vg_replace_malloc.c:236)
==27862== by 0x40E861A: __cxa_allocate_exception (in /usr/lib/libstdc++.so.6.0.14)
==27862== by 0x80487AE: main (smart_pointers.cpp:10)
==27862==
==27862== LEAK SUMMARY:
==27862== definitely lost: 0 bytes in 0 blocks
==27862== indirectly lost: 0 bytes in 0 blocks
==27862== possibly lost: 100 bytes in 1 blocks
==27862== still reachable: 4 bytes in 1 blocks
==27862== suppressed: 0 bytes in 0 blocks
==27862==
==27862== For counts of detected and suppressed errors, rerun with: -v
==27862== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 19 from 8)
Does using smart pointers guarantee the allocated resources will be destroyed even if an exception shows up?
If an exception is not handled, then it's implementation-defined whether the stack will be unwound before calling
std::terminate
.If you handle the exception, then the smart pointer will work as expected.
Reference:
C++11 15.5.1 The
std::terminate()
functionWhen
std::terminate()
is called (as is the case for an uncaught exception), normal cleanup is not run (at least for the stack-frame ofmain()
), and as such the memory you've allocated in that stack frame leaks, even though it's supposedly managed by a smart-pointer. When you're catching thestd::bad_alloc
inmain()
, and return normally, the smart-pointer will do it's duty.If the exception is not caught, then the stack unwinding is implementation specific. Therefore in your case, it does not release the memory.
Also, auto_ptr is no longer recommended.
Use std::unique_ptr :