I'm experimenting with smart pointers and experiencing a problem with the unique_ptr
. What sparked this is that in VS2013 I am using .release()
in a class destructor and it's not releasing (using TRACE
) yet it is with .reset
. I have some sample code at the following URL: IDEOne Example Code
I've created a class containing two unique_ptr
members. These members get assigned in the constructor and in theory, according to smart pointer theory as I understand it, should get delete
d automatically. They are assigned a custom struct as a custom deleter, as defined below:
struct Deleter
{
void operator()(TCHAR* p) const
{
std::cout << "Deleter deleting .." << p << '\n';
delete[] p;
}
};
The unique_ptr
members are declared as:
unique_ptr<TCHAR[], Deleter> szMySimpleString;
unique_ptr<TCHAR[], Deleter> szMySimpleStringLeak;
the unique_ptr
members are then defined in the constructor of a class as:
szMySimpleString = unique_ptr<TCHAR[], Deleter>(new TCHAR[255], Deleter());
szMySimpleStringLeak = unique_ptr<TCHAR[], Deleter>(new TCHAR[255], Deleter());
strcpy(this->szMySimpleString.get(), "szMySimpleString");
strcpy(this->szMySimpleStringLeak.get(), "szMySimpleStringLeak");
When this class is deleted, I have the destructor running .release()
in one example, .reset()
in another. Each has behavior that I wouldn't expect. .release()
is running the deleter on the wrong unique_ptr
while .reset
runs the deleter on both unique_ptr
's.
Please see the full code at the link at the beginning of this question (Note: There are 3 commented-out areas to run one at a time to see each effect).
If I run:
szMySimpleStringLeak.release();
I get the results:
Doing Stuff ...
Contents of szMySimpleString: szMySimpleString
Contents of szMySimpleStringLeak: szMySimpleStringLeak
MyStupidClass Destructor running...
Deleter deleting ..szMySimpleString
If I run:
szMySimpleString.release();
I get the results:
Deleter deleting ..szMySimpleStringLeak
and if I run:
szMySimpleString.reset();
I get the results:
MyStupidClass Destructor running...
Deleter deleting ..szMySimpleString
Deleter deleting ..szMySimpleStringLeak
I'd appreciate any input to why this behavior is unexpected (or rather why I should expect it).
Thanks!
unique_ptr::release
relinquishes ownership of the managed object without destroying it. unique_ptr::reset
will destroy the object using the supplied deleter.
It's not that calling release()
is running the deleter on the wrong unique_ptr
instance, but that it's not running the deleter on the instance on which you called release()
. The deleter for the other instance is automatically called by the unique_ptr
's destructor, which is implicitly invoked by your class' destructor.
If you leave the unique_ptr
instances alone, and called neither reset()
nor release()
on either of them, then you'll see the expected behavior when your class' destructor executes.
unique_ptr::release()
does not delete the internal pointer, instead it releases the ownership of it. See the doc .
So in your case calling release()
just causes memory leak.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.