我一直在做一个作业,让我们使用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。
你的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
如何检查析构函数是否正常工作?我正在使用视觉对象 演播室。
您可以放置一个断点来检查代码是否被命中。