智能指针控制块内部机械

Ric*_*lly 3 c++ shared-ptr weak-ptr c++11

我想知道释放为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;
}
Run Code Online (Sandbox Code Playgroud)
  1. 用虚拟分配的内存构建一个shared_ptr。分配了控制块,并将其虚拟指针设置为“虚拟”
  2. 从shared_ptr构建weak_ptr。两个智能指针共享相同的控制块地址。
  3. 共享指针被破坏。称为虚拟dtor(在“地标”之前打印“ dtor”)。控制块仍然有效,直到程序结束。

我对这些评论正确吗?
在这些步骤中,控制块内会发生什么(详细)?

编辑:make_shared情况会怎样?
有一种分配包含Dummy对象和控制块。
这是否涉及使用两个不同objets的新放置?
还是包含原始对象的结构?

#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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Que*_*tin 6

是的你是对的。

发生情况的详细信息:

  1. 控制块已创建并绑定到share_ptr. shared_count = 1, weak_count = 0.
  2. 绑定weak_pointer到控制块。shared_count = 1, weak_count = 1.
  3. 最后一个(唯一的)shared_pointer死亡,摧毁了物体。控制块由 维护weak_ptrshared_count = 0, weak_count = 1.
  4. (结束main()最后一个(唯一)weak_ptr死亡,并且shared_count = 0。没有人再绑定到控制块,因此最后一个weak_ptr会破坏控制块。

  • @SombreroChicken 为了弱者,我必须继续前进——这已经足够英勇了,我喜欢它。 (2认同)

Oth*_*oun 5

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

在此处输入图片说明

这基本上就是它的工作方式,当最后一个shared_ptr超出范围时,指向对象的对象将被删除(其内存已取消分配),但是计数管理器仍然存在,因为weak_ptr需要知道正在发生的事情(如果存在指针)反对与否。

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

  • 对象已销毁(调用了析构函数),但未取消分配 (2认同)