【问题标题】:Is calling an object's destructor equivalent to calling delete on the object?调用对象的析构函数是否等同于在对象上调用 delete?
【发布时间】:2020-04-29 17:34:24
【问题描述】:
class TrieTree{
private:
    string ch;
    unordered_map<string, TrieTree*> child;
public:
    TrieTree(string val): ch(val){}
    ~TrieTree(){
        for(unordered_map<string, TrieTree*>::iterator itr = this->child.begin();
            itr != this->child.end();
            itr++){

            (itr->second)->~TrieTree();
        }
    }
};

我担心上述析构函数是否会造成内存泄漏,因为我不确定调用对象的析构函数是否等同于调用对象的删除。我不能直接在对象上调用 delete,因为目的是递归地删除对象的子对象。通过在(itr-&gt;second)-&gt;~TrieTree(); 之后调用delete (itr-&gt;second);,我遇到了分段错误,所以我猜该对象可能在其析构函数之后被删除了?

【问题讨论】:

  • delete 相当于调用析构函数,然后释放对象占用的存储空间。如果您使用delete 以及显式析构函数调用,那么您会调用析构函数两次,这会导致未定义的行为。您不只是使用delete 的理由毫无意义。
  • 这个类也不遵循三规则(/五/零)
  • 考虑使用unordered_map&lt;string, unique_ptr&lt;TrieTree&gt;&gt;,如果它适合您的应用程序(我们不能仅根据发布的内容来判断),那么您根本不需要进行任何手动内存管理
  • 或四(半)规则。
  • 一般来说,清理一棵树的方式是先删除一个节点的子节点,然后再删除该节点。

标签: c++ class memory destructor


【解决方案1】:

调用对象的析构函数是否等同于调用对象的delete?

不,不等价。

调用对象的析构函数会破坏它。

在指针上调用delete 会破坏指向的对象并释放内存。行为是未定义的,除非指向是通过分配 new 返回的。

如果您使用new 分配内存并且只调用析构函数而不解除分配,那么您将泄漏内存。如果您销毁该对象并在指向的对象被销毁时尝试使用delete,那么您的程序的行为将是未定义的。


附:避免使用拥有裸指针。

【讨论】:

    猜你喜欢
    • 2016-01-23
    • 2013-06-25
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    • 2016-09-26
    相关资源
    最近更新 更多