【发布时间】:2017-02-15 23:29:13
【问题描述】:
我已经开始使用 trie 实现字典。基本上,我有一个根节点,它有一个定义(指向 T 的指针,表示与键关联的 de 值)和子节点(指向包含指向 256 个节点的指针的数组的指针,每个字母一个)。检查定义:
template<typename T>
class DiccString {
public:
DiccString() : root(NULL);
DiccString(const DiccString<T>&);
~DiccString() {delete root;}
void define(const string& key, const T& value);
bool isDefined(const string& key) const;
const T& getDefinition(const string& key) const;
T& getDefinition(const string& key);
void remove(const string& key);
const Set<string>& keys() const;
private:
struct Node{
Node** childs;
T* definition;
Node(){
std::cout << "Node has been created " << this << std::endl;
childs = new Node*[256];
definition = NULL;
}
~Node(){
std::cout << "Node has been deleted " << this << std::endl;
delete definition;
delete [] childs;
}
};
Node* root;
};
因此,如果我想存储值为 14 的“John”(T 将是 int 所以),假设没有其他密钥,那么我将创建一个根,然后在 root->childs[(int)'j'] 创建另一个节点“nodeJ”,然后创建 nodeJ->childs[(int)'o'],依此类推,直到到达最后一个节点“nodeN”,其中将包含值 ( nodeN->definition = 14)。
问题是当我这样做时:
int main() {
DiccString<int> d;
d.define("john",20);
d.define("jane",25);
return 0;
}
然后我希望所有创建的节点都被销毁,但看看输出:
Node created 0x61fc20 // root
Node created 0x620860 // for letter 'j'
Node created 0x621090 // for letter 'o' (child of 'j' 0x620860)
Node created 0x6218c0 // for letter 'h' (child of 'o' 0x621090)
Node created 0x6220f0 // for letter 'n' (child of 'h' 0x6218c0), value: 20
Node created 0x622990 // for letter 'a' (child of 'j' 0x620860)
Node created 0x6231c0 // for letter 'n' (child of 'a' 0x622990)
Node created 0x6239f0 // for letter 'e' (child of 'n' 0x6231c0), value: 25
Node deleted 0x61fc20 // root
只是根被删除。显然,当在Node 的析构函数中执行delete [] childs 时,它并没有删除数组的所有元素,我确信这些元素存在:例如,在调用 root 的析构函数的情况下(这是唯一真正被调用的),我评估了childs[(int)'j'],它肯定是0x620860,所以我知道它应该(至少)在执行delete [] childs时调用这个元素的析构函数,对吧?
我做错了什么?
【问题讨论】:
标签: c++ arrays destructor trie