删除[]不会调用元素析构函数

时间:2016-10-07 04:05:57

标签: c++ arrays destructor trie

我已经开始使用 trie 实现字典了。基本上,我有一个根节点,它有一个定义(指向T的指针,表示与键相关的de值)和childs(指向包含指向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;
};

所以,如果我想存储&#34; John &#34;值 14 T将是int所以),假设没有其他密钥,那么我将创建一个根,然后在root-&gt; {{1我将创建另一个节点&#34; nodeJ&#34;,然后是nodeJ-&gt; childs[(int)'j'],依此类推,直到到达最后一个节点&#34; nodeN&#34;,它将包含该值(childs[(int)'o'])。

问题出在我做的时候:

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 的析构函数中执行delete [] childs时,它并没有删除数组的所有元素,我确信它们存在:例如,在调用root的析构函数(实际上是唯一被调用的函数)的情况下,我评估了Node,它肯定是0x620860,所以我知道它应该调用这个元素的析构函数(at至少)当它执行childs[(int)'j']时,对吧?

我做错了什么?

2 个答案:

答案 0 :(得分:2)

childs的类型为Node**,它是指向指针的指针。你为它分配了一个Node*指针数组。

delete[] childs删除此分配,即仅删除指针的内存,而不删除指针指向的对象。

我们没有看到您实际分配Node的代码,但是您必须以某种方式存储256个分配的Node*中的哪一个实际指向有效的Node对象。也许你通过用NULL指针标记指针来做到这一点?在这种情况下,您可能希望执行以下操作:

for(int i=0; i<256; ++i) {
    delete childs[i];
}

我还应该注意,如果Node指针的数量是固定的,你应该使用静态数组,否则你应该使用std::vector

答案 1 :(得分:0)

打印输出仅用于销毁Node个对象而不是Node *。您可以使用调试器检查行为是否正确。

请注意,如果您在构造函数/析构函数中具有对称性,则可能更清楚,而不是在define()中进行延迟分配。当释放DiccString时,请务必正确处理error: Name clash for '<pstage/lib>libboost_atomic.so.1.62.0' error: error: Tried to build the target twice, with property sets having error: these incompatible properties: error: error: - <debug-symbols>on <inlining>off <optimization>off <runtime-debugging>on <variant>debug error: - <debug-symbols>off <define>NDEBUG <inlining>full <optimization>speed <runtime-debugging>off <variant>release error: error: Please make sure to have consistent requirements for these error: properties everywhere in your project, especially for install error: targets. 为空的情况。