【问题标题】:Smart pointers' control block internal machinery智能指针的控制块内部机械
【发布时间】:2015-10-22 00:58:40
【问题描述】:

我想知道释放分配给shared_ptr和weak_ptr共享的内部控制块的内存的确切条件是什么。
我猜控制块包含一个 shared_ptr 计数器和一个weak_ptr 计数器。

#include <memory>
#include <iostream>

struct Dummy
{
    Dummy() { std::cout << "ctor" << std::endl; }
    ~Dummy() { std::cout << "dtor" << std::endl; }
};

int main()
{
    auto dummy = new Dummy();
    auto wp = std::weak_ptr<Dummy>(); // pointing to nothing

    {
        auto sp = std::shared_ptr<Dummy>(dummy); // 1
        wp = sp; // 2
    } // 3
    std::cout << "Land mark" << std::endl;
}
  1. 使用虚拟分配内存构建 shared_ptr。控制块被分配,它的 Dummy 指针被设置为“dummy”
  2. 从 shared_ptr 构建一个weak_ptr。两个智能指针共享相同的控制块地址。
  3. 共享指针被破坏。调用虚拟 dtor(“dtor”打印在“Land mark”之前)。控制块在程序结束前仍然存在。

我对这些 cmets 的看法是否正确?
在这些步骤中,控制块内会发生什么(详细)?

编辑:make_shared case 会发生什么?
有一个分配包含虚拟对象和控制块。
这是否涉及放置新以使用两个不同的对象?
或者它是一个包含原始对象的结构?

#include <memory>
#include <iostream>

struct Dummy
{
    Dummy() { std::cout << "ctor" << std::endl; }
    ~Dummy() { std::cout << "dtor" << std::endl; }
};

int main()
{
    auto wp = std::weak_ptr<Dummy>(); // pointing to nothing
    {
        auto sp = std::make_shared<Dummy>();
        wp = sp;
    }
}

【问题讨论】:

    标签: c++ c++11 shared-ptr weak-ptr


    【解决方案1】:

    这是 valgrind massif 为您的测试显示的内容,(如果您不习惯 valgrind )这是按时间分配的内存量,首先是指向对象,然后是计数管理器,然后是指向对象被释放

    这基本上是它的工作原理,当最后一个 shared_ptr 超出范围时,指向的对象被删除(它的内存被取消分配),但计数管理器仍然存在,因为weak_ptr需要知道发生了什么,如果有是否是指向对象。

    但有时情况并非如此,如果你使用make_shared,make_shared 实际上只为对象和计数管理器使用了一个分配,在这种情况下,分配的内存将保留在那里直到最后一个weak_ptr消失超出范围

    【讨论】:

    • 您的意思是在我的情况下使用 make_shared 时无法删除虚拟分配的对象?
    • 对象被销毁(析构函数被调用)但没有被释放
    • 我对细节的回答并不完全满意,但我想你的回答是最相关的。
    • 这里有一个cppcon video,解释的很好,他在9:40之后谈到了shared_ptr
    【解决方案2】:

    是的,你是对的。

    发生的细节:

    1. 控制块被创建并绑定到share_ptr。 shared_count = 1,weak_count = 0。
    2. weak_pointer 绑定到控制块。 shared_count = 1,weak_count = 1。
    3. 最后一个(唯一的)shared_pointer 死了,摧毁了对象。控制块由weak_ptr 维护。 shared_count = 0, weak_count = 1.
    4. (main() 结束) 最后一个(唯一的)weak_ptr 死了,shared_count = 0。没有人再绑定到控制块了,所以最后一个weak_ptr 会破坏控制块。

    【讨论】:

    • 你是控制块
    • @SombreroChicken 为了弱者,我必须继续前进——这已经够英勇了,我喜欢。
    猜你喜欢
    • 2017-05-16
    • 1970-01-01
    • 2017-02-16
    • 2016-10-09
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多