我一直致力于一项任务,我们使用trie树将字典中的单词添加到树中,然后搜索它。我坚持的部分是类析构函数。这是我第一次不得不处理析构函数/内存管理,而我在搜索我目前拥有的资源后,下面的内容是我最好的猜测。
我是否在正确的轨道上?每个节点有27个子节点(字母和分隔符),所以我希望它从叶子到根节点都删除它们。
class Trie
{
private:
TrieNode *_root = nullptr;
TrieNode *_current = nullptr;
TrieNode *_child = nullptr;
string current_word;
bool setRoot = false;
protected:
public:
Trie()
{
_root = new TrieNode{};
}
virtual ~Trie()
{
//TODO: clean up memory
DestroyRecursive(_root);
}
void Trie::DestroyRecursive(TrieNode* node)
{
if (node != nullptr)
{
for (TrieNode* child : node->getChildren())
{
delete(child);
}
}
}
如何检查析构函数是否正常工作?我正在使用Visual Studio。
答案 0 :(得分:0)
您的DestroyRecursive
实际上并非递归
您需要在叶节点上调用delete
并递归有子节点的节点。
void Trie::DestroyRecursive(TrieNode* node)
{
if (node != nullptr)
{
if (node->getChildren().size() == 0)
{
// delete the leaf node
delete(node);
return;
}
for (TrieNode* child : node->getChildren())
{
DestroyRecursive(child);
}
}
}
可能出错,具体取决于您对TrieNode
结构的依赖性。例如,它是否有一个非平凡的析构函数?
通过将原始指针替换为std::shared_ptr
,可以避免很多这种情况std::shared_ptr<TrieNode> _root = nullptr;
vector<shared_ptr<TrieNode>> _child = nullptr;
Trie()
{
_root = std::make_shared<TrieNode>();
}
然后在大多数情况下,您不需要析构函数。超出范围时,std::vector
和shared_ptr
将负责在适当的内存上调用delete
。
请注意,所有权中没有循环依赖性。如果将来添加父指针,则必须是原始指针或std::weak_ptr
如何检查析构函数是否正常工作?我正在使用Visual 工作室。
您可以设置breakpoint来检查代码是否被点击。