I don't know the details of your SmartPtr
class.
In any case, if you have a constructor like this:
SmartPtr::SmartPtr(Pointee * p):_pointee(new Pointee(*p)) {}
and this is the destructor:
SmartPtr::~SmartPtr() { delete _pointee; }
then with this code:
SmartPtr pTime0(new Time(0,0,1));
you leak one instance of Time(0,0,1)
.
In fact, you have one more new
than delete
(2 new
s and 1 delete
):
Step #1: You call new Time(0,0,1)
and create a new object on the heap.
(new
count == 1)
Step #2: You pass this pointer to SmartPtr
constructor, which deep copies previously created object and allocates a new copy on the heap, and keeps track of this copy via its _pointee
data member.
(new
count == 2)
Step #3: When the SmartPtr
destructor runs, it delete
s the instance pointed by _pointee
data member, but you leaked the firts Time(...)
created on the heap with new Time(0,0,1)
.
(delete
count == 1; new
count == 2)
A possible fix for that could be to just have this constructor:
SmartPtr::SmartPtr(Pointee * p)
: _pointee(p) // <--- transfer ownerhsip (no deep copies) !
{}
An easy way to identify potential leaks in these cases is to put some console tracing output in Time
class constructors and destructor, and check that the trace output of destructor matches the ones of constructors, e.g.:
Time::Time(....)
{
// Do construction work....
std::cout << "Time constructor\n";
}
Time::~Time(....)
{
// Do destructor work....
std::cout << "Time destructor\n";
}
The total count of "Time constructor"
strings should match the total count of "Time destructor"
strings.