即使 valgrind 没有显示内存泄漏,我是否应该在 c++11 的析构函数中清除 unique_ptr 的向量
Shall I clear a vector of unique_ptr in destructor in c++11 even if valgrind doesn't show memory leak
给出下面的 Holder
class:
class Holder {
string name;
std::vector<std::unique_ptr<Object>> objects;
public:
Holder(string name): name(name){
}
~Holder(){};
Holder & operator=(const Holder & holder) = delete;
vector<unique_ptr<Object>> const& Holder::getContent()const{
return this->objects;
}
void Holder::add(unique_ptr<Object> objPtr){
this->objects.push_back(move(objPtr));
}
};
如果我在下面的方法中调用我的 Holder 对象:
void HolderTest::addObject(){
Holder *holder = new Holder("bag");
holder->add(unique_ptr<Object>(new Object("test")));
vector<unique_ptr<Object>> const& objects = holder->getContent();
const std::string name = objects[0].get()->name();
CPPUNIT_ASSERT_EQUAL((string)"test", name);
delete holder;
}
我的问题是:我是否应该在 Holder 析构函数中调用 unique_ptr 的 vector 的 clear 方法来避免内存泄漏,如下所示?
~Holder(){
this->objects.clear();
};
我的另一个问题是,我仍然可以使用 "Valgrind Tools Integration" 版本 3.0.0.201502180018 来查找 c++11 应用程序中的内存泄漏,还是无法在 c++11 程序中查找内存泄漏?
您不必手动调用 clear
。 std::vector<T>
的析构函数会自动调用 std::unique_ptr<T>
的析构函数。
与内置指针相比,智能指针的主要优点是您不必处理手动清理。
从技术上讲,您没有任何内存泄漏。当你删除你的 holder 时,vector
中的所有元素都被销毁(因为 Holder 的析构函数已经清除了 vector),而 unique_ptr 的析构函数实际上释放了为添加的对象分配的内存。
我觉得奇怪的是,对于您的情况,最简单的解决方案可能是使用
std::vector< Object> objects;
objects.emplace_back("test");
效率更高,阅读更简单。
编辑:问题的第二部分,Valgrind 可能有误报(当你没有泄漏时警告泄漏),但我从未听说过 Valgrind 报告假阴性(当你有泄漏时根本没有泄漏)泄漏)。
编辑 2:
#include <utility> // std::forward
#include <vector>
//...
template< typename... Args>
void Holder::add( Args&&... args){
objects.emplace_back( std::forward< Args>(args)...);
}
用法:
holder.add("Test");
给出下面的 Holder
class:
class Holder {
string name;
std::vector<std::unique_ptr<Object>> objects;
public:
Holder(string name): name(name){
}
~Holder(){};
Holder & operator=(const Holder & holder) = delete;
vector<unique_ptr<Object>> const& Holder::getContent()const{
return this->objects;
}
void Holder::add(unique_ptr<Object> objPtr){
this->objects.push_back(move(objPtr));
}
};
如果我在下面的方法中调用我的 Holder 对象:
void HolderTest::addObject(){
Holder *holder = new Holder("bag");
holder->add(unique_ptr<Object>(new Object("test")));
vector<unique_ptr<Object>> const& objects = holder->getContent();
const std::string name = objects[0].get()->name();
CPPUNIT_ASSERT_EQUAL((string)"test", name);
delete holder;
}
我的问题是:我是否应该在 Holder 析构函数中调用 unique_ptr 的 vector 的 clear 方法来避免内存泄漏,如下所示?
~Holder(){
this->objects.clear();
};
我的另一个问题是,我仍然可以使用 "Valgrind Tools Integration" 版本 3.0.0.201502180018 来查找 c++11 应用程序中的内存泄漏,还是无法在 c++11 程序中查找内存泄漏?
您不必手动调用 clear
。 std::vector<T>
的析构函数会自动调用 std::unique_ptr<T>
的析构函数。
与内置指针相比,智能指针的主要优点是您不必处理手动清理。
从技术上讲,您没有任何内存泄漏。当你删除你的 holder 时,vector
中的所有元素都被销毁(因为 Holder 的析构函数已经清除了 vector),而 unique_ptr 的析构函数实际上释放了为添加的对象分配的内存。
我觉得奇怪的是,对于您的情况,最简单的解决方案可能是使用
std::vector< Object> objects;
objects.emplace_back("test");
效率更高,阅读更简单。
编辑:问题的第二部分,Valgrind 可能有误报(当你没有泄漏时警告泄漏),但我从未听说过 Valgrind 报告假阴性(当你有泄漏时根本没有泄漏)泄漏)。
编辑 2:
#include <utility> // std::forward
#include <vector>
//...
template< typename... Args>
void Holder::add( Args&&... args){
objects.emplace_back( std::forward< Args>(args)...);
}
用法:
holder.add("Test");