weak_ptr、make_shared 和内存释放

weak_ptr, make_shared and memory deallocation

当至少有一个 weak_ptr 存在时,shared_ptr 的控制块保持活动状态。如果共享指针是用 make_shared 创建的,这意味着对象的整个内存都被分配了。 (对象本身已被正确销毁,但由于控制块和对象的内存是在一个块中分配的,就像 make_shared 所做的那样,它们只能一起释放。)

我的理解正确吗?

似乎这种行为代表了一个问题,例如在著名的"cache example"中。对象的内存将永远保持分配状态。

在任何实际情况下都会有问题吗? shared_ptr 是否应该在这种情况下使用构造函数创建(大对象并打算使用 weak_ptrs)?

Is my understanding correct?

是的。如果您的 weak_ptr 明显比(大)对象长,并且您的内存紧张,那么避免 make_shared.

可能是有益的

然而,这里的 "large" 是以 sizeof 衡量的,许多概念上的 "large" 对象(例如,除了 std::array 之外的大多数标准容器)都非常小该指标,因为它们分配了额外的内存来存储它们的内容,一旦对象被销毁,这些内容就会被释放。

我在 VS2013 中试过这个,你是完全正确的。当最后一个 shared_ptr 被销毁时调用析构函数,因此与该对象关联的任何其他对象或内存都将被销毁,但如果 shared_ptr 是用 make_shared 创建的,则内存永远不会被销毁直到最后一个 weak_ptr 是。

我认为如果 lock() 失败,清理或重置 weak_ptrs 总是好的,因为即使没有 make_shared 它仍在使用一些内存。