避免C+中的内存泄漏+;班 我用下面的头文件定义了C++类: class EarleyParser { public: EarleyParser(); virtual ~EarleyParser(); void initialize( string filePath, bool probabilityParse ); private: bool probabilityParser; typedef unordered_map< string, list<Production>* > productionHashTable; productionHashTable earlyHashTable; };
如果要存储指向地图中任何内容的指针,则必须手动浏览地图并删除每个指针。通常在类中,您会坚持使用RAII(资源获取是初始化),在构造函数中构造东西,在析构函数中销毁 但是,指向容器的指针不是一个好主意。你为什么需要一个指针?使用指向避免C+中的内存泄漏+;班 我用下面的头文件定义了C++类: class EarleyParser { public: EarleyParser(); virtual ~EarleyParser(); void initialize( string filePath, bool probabilityParse ); private: bool probabilityParser; typedef unordered_map< string, list<Production>* > productionHashTable; productionHashTable earlyHashTable; };,c++,pointers,memory-leaks,unordered-map,delete-operator,C++,Pointers,Memory Leaks,Unordered Map,Delete Operator,如果要存储指向地图中任何内容的指针,则必须手动浏览地图并删除每个指针。通常在类中,您会坚持使用RAII(资源获取是初始化),在构造函数中构造东西,在析构函数中销毁 但是,指向容器的指针不是一个好主意。你为什么需要一个指针?使用指向列表的指针试图解决什么问题 使用像std::unique_ptr这样的智能指针比原始指针好得多。原始指针应该是最后的手段,而不是当你想不出更好的方法时,第一件要抓到的东西。如果你要在地图中存储指向任何东西的指针,你必须手动浏览地图并删除每个指针。通常在类中,您会坚持使用
列表的指针试图解决什么问题
使用像std::unique_ptr
这样的智能指针比原始指针好得多。原始指针应该是最后的手段,而不是当你想不出更好的方法时,第一件要抓到的东西。如果你要在地图中存储指向任何东西的指针,你必须手动浏览地图并删除每个指针。通常在类中,您会坚持使用RAII(资源获取是初始化),在构造函数中构造东西,在析构函数中销毁
但是,指向容器的指针不是一个好主意。你为什么需要一个指针?使用指向列表的指针试图解决什么问题
使用像std::unique_ptr
这样的智能指针比原始指针好得多。原始指针应该是最后的手段,而不是当你想不出更好的东西时,第一件要抓住的东西。使用:
typedef unordered_map< string, std::unique_ptr<list<Production> > > productionHashTable;
typedef无序映射productionHashTable;
相反。这样,您就不必担心管理内存。使用:
typedef unordered_map< string, std::unique_ptr<list<Production> > > productionHashTable;
typedef无序映射productionHashTable;
相反。这样,您就不必担心内存管理。编译器合成析构函数不会删除您放在映射中的动态分配列表,因此您必须自己完成。在这种情况下,您只需迭代地图并删除每个元素的second
成员:
EarleyParser::~EarleyParser() {
for ( productionHashTable::iterator i = earlyHashTable.begin(); i != earlyHashTable.end(); ++i )
delete i->second;
}
更好的方法是在地图中放置列表,而不是指向列表的指针。在这种情况下,编译器将自动处理销毁,如下所示:
typedef unordered_map< string, list<Production> > productionHashTable;
typedef无序映射productionHashTable;
编译器合成析构函数不会删除您放在映射中的动态分配列表,因此您必须自己删除。在这种情况下,您只需迭代地图并删除每个元素的second
成员:
EarleyParser::~EarleyParser() {
for ( productionHashTable::iterator i = earlyHashTable.begin(); i != earlyHashTable.end(); ++i )
delete i->second;
}
更好的方法是在地图中放置列表,而不是指向列表的指针。在这种情况下,编译器将自动处理销毁,如下所示:
typedef unordered_map< string, list<Production> > productionHashTable;
typedef无序映射productionHashTable;
您需要澄清谁拥有列表
对象,这些对象由EarlyParser
拥有。如果EarlyParser
拥有它们,那么您需要释放这些资源。您可以通过迭代列表并在每个取消引用的迭代器上调用delete
(notdelete[]
)。或者您可以存储unique\u ptr
。另一方面,最简单的解决方案是存储list
,除非您确实有非常充分的理由来存储指针。您需要澄清谁拥有EarlyParser
拥有的list
对象。如果EarlyParser
拥有它们,那么您需要释放这些资源。您可以通过迭代列表并在每个取消引用的迭代器上调用delete
(notdelete[]
)。或者您可以存储unique\u ptr
。另一方面,最简单的解决方案是存储列表
,除非您确实有非常充分的理由来存储指针。实际上调用它所拥有的对象的析构函数,这意味着将调用列表
的析构函数。
请注意:
请注意,如果元素是指针,则指向的对象不会被销毁
这意味着,你必须自己清除这些记忆。是的,遍历容器并删除元素1by1就可以了。正如其他回答者提到的,保持这样的指针不是一个好主意。实际上调用它所拥有的对象的析构函数,这意味着将调用列表的析构函数。
请注意:
请注意,如果元素是指针,则指向的对象不会被销毁
这意味着,你必须自己清除这些记忆。是的,遍历容器并删除元素1by1就可以了。正如其他回答者所提到的,保持这样的指针不是一个好主意。因为您使用的是指向std::list
的原始指针,所以您必须在映射的生命周期中或在清理其析构函数中的EarleyParser
对象时自己删除它
您可以在析构函数中使用如下内容:
for ( auto it = productionHashTable.begin();
it != productionHashTable.end(); ++it )
{
delete it->second;
}
productionHashTable.clear()
请注意,最后一行并不是绝对必要的,因为它将在EarleyParser
对象被破坏时被清除,但很明显,在删除映射中的值后,不能使用它们 由于您使用的是指向std::list
的原始指针,因此您必须在映射的生命周期中或在清理其析构函数中的EarleyParser
对象时自己删除它
您可以在析构函数中使用如下内容:
for ( auto it = productionHashTable.begin();
it != productionHashTable.end(); ++it )
{
delete it->second;
}
productionHashTable.clear()
请注意,最后一行并不是绝对必要的,因为它将在EarleyParser
对象被破坏时被清除,但很明显,在删除映射中的值后,不能使用它们 如果此对象拥有此列表,则应将其删除。使用共享指针而不是指向列表的原始指针-然后它将删除自身。如果我将其留给默认构造函数来释放分配的内存-您肯定是指析构函数?@Component10-of