【问题标题】:Cyclic dependency of shared_ptr [closed]shared_ptr的循环依赖[关闭]
【发布时间】:2022-01-23 04:01:39
【问题描述】:

我有一个函数,其中 shared_ptr 的循环依赖。因此我有内存泄漏。我该如何解决它?


void down(std::shared_ptr<Node> &curr, uint8_t level) {
    curr->left->parent = curr;
    curr->right->parent = curr;

    if (!curr->left->visited_) {
        curr = curr->left;
        curr->visited_ = true;
    } else {
        curr = curr->right;
        curr->visited_ = true;
    }

    curr->level_ = curr->parent->level_ + 1;
    while (curr->level_ != level) {
        if (curr->left == nullptr) {
            curr->left = std::make_shared<Node>();
        }
        curr->left->parent = curr;
        if (curr->right == nullptr) {
            curr->right = std::make_shared<Node>();
        }
        curr->right->parent = curr;
        curr = curr->left;
        curr->visited_ = true;
        curr->level_ = curr->parent->level_ + 1;
    }
}

【问题讨论】:

  • 简单的解决方案是不要将 shared_ptr 用于您的父指针。对它们使用weak_ptr 或原始/C 风格的指针。
  • 我猜你需要一个从孩子到父母的弱指针。但是,你能显示一个minimal reproducible example吗?至少要查看您的Node 结构。
  • ``` struct Node { std::weak_ptr parent; std::shared_ptr 左; std::shared_ptr 对;整数值_ = -1;诠释级别_;布尔访问_ =假; }; ```

标签: c++ memory-leaks shared-ptr


【解决方案1】:

Share_ptr 不是解决所有内存问题的灵丹妙药。它很神奇,因为它可以让你以更复杂的方式把事情搞砸。

这里你显然有一个循环依赖,它不能被引用计数指针正确处理。

典型的解决方案是使用weak_ptr 打破循环。子节点不需要(通常)使父母保持活动状态,因此对于您的示例而言,这可能是最简单的解决方法(将 parent 替换为weak_ptr)。

更好的解决方案是认真考虑数据的所有权和生命周期。删除根目录后,您的程序的其他部分是否应该使子树保持活动状态?在您决定不再需要树之后,他们甚至应该使用子树吗?
也许不使用 shared_ptr 会是一个更好的选择。也许您可以为孩子们使用 unique_ptr 来更好地表达所有权和寿命。也许您需要更好地查看上下文以了解为什么在您仍在使用它的数据时删除树(我猜这可能是一个更大的问题)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-28
    相关资源
    最近更新 更多