我正在尝试使用智能指针并遇到unique_ptr
的问题。引发这种情况的是,在VS2013中,我在类析构函数中使用.release()
并且它没有释放(使用TRACE
)但它与.reset
一致。
我在以下网址上有一些示例代码:IDEOne Example Code
我创建了一个包含两个unique_ptr
成员的类。这些成员在构造函数中被赋值,理论上,根据我理解的智能指针理论,它应该自动获得delete
d。它们被分配了一个自定义结构作为自定义删除器,如下所述:
struct Deleter
{
void operator()(TCHAR* p) const
{
std::cout << "Deleter deleting .." << p << '\n';
delete[] p;
}
};
unique_ptr
成员被声明为:
unique_ptr<TCHAR[], Deleter> szMySimpleString;
unique_ptr<TCHAR[], Deleter> szMySimpleStringLeak;
然后在类的构造函数中将unique_ptr
成员定义为:
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");
删除此类后,我的析构函数在一个示例中运行.release()
,在另一个示例中运行.reset()
。每个人都有我不希望的行为。 .release()
正在错误unique_ptr
上运行删除工具,而.reset
在unique_ptr
上运行删除工具。
请在此问题开头的链接中查看完整代码(注意:有3个注释区域可以一次运行一个以查看每个效果)。
如果我跑:
szMySimpleStringLeak.release();
我得到了结果:
Doing Stuff ...
Contents of szMySimpleString: szMySimpleString
Contents of szMySimpleStringLeak: szMySimpleStringLeak
MyStupidClass Destructor running...
Deleter deleting ..szMySimpleString
如果我跑:
szMySimpleString.release();
我得到了结果:
Deleter deleting ..szMySimpleStringLeak
如果我跑:
szMySimpleString.reset();
我得到了结果:
MyStupidClass Destructor running...
Deleter deleting ..szMySimpleString
Deleter deleting ..szMySimpleStringLeak
我很感激为什么这种行为是出乎意料的(或者更确切地说,为什么我应该期待它)。
谢谢!
答案 0 :(得分:4)
unique_ptr::release
放弃托管对象的所有权而不破坏托管对象。 unique_ptr::reset
将使用提供的删除器销毁对象。
并非调用release()
正在错误的unique_ptr
实例上运行删除程序,而是它没有在您调用release()
的实例上运行删除程序unique_ptr
1}}。另一个实例的删除器由unique_ptr
的析构函数自动调用,这个析构函数由您的类隐式调用&#39;析构函数。
如果您单独留下reset()
个实例,并且未对其中任何一个调用release()
或{{1}},那么当您的班级&#39;时,您会看到预期的行为。析构函数执行。
答案 1 :(得分:1)
unique_ptr::release()
不会删除内部指针,而是会释放它的所有权。 See the doc
因此,在您的情况下,调用release()
只会导致内存泄漏。