为什么共享指针不删除内存?

时间:2019-10-03 16:47:18

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

shared_ptr<string> pNico(new string("Nico"));
shared_ptr<string> pJutta(new string("Jutta"));
// put them multiple times in a container
vector<shared_ptr<string>> whoMadeCoffee;
whoMadeCoffee.push_back(pJutta);
whoMadeCoffee.push_back(pJutta);
whoMadeCoffee.push_back(pNico);
whoMadeCoffee.push_back(pJutta);
whoMadeCoffee.push_back(pNico);

pNico = nullptr;         
whoMadeCoffee.resize(2);
     

在程序的最后,当字符串的最后一个所有者被破坏时,共享指针将对其所引用的对象调用delete。这种删除不一定必须在范围的末尾进行。例如,将nullptr分配给pNico或调整向量的大小,使其仅包含前两个元素,将删除以nico初始化的字符串的最后一个所有者。

(来自Josuttis,Nicolai M.。“ C ++标准库”。)

我的问题是,为什么在上述情况下不能保证在范围的末尾删除"Nico"对象的内存?

尽管我们可以这样做

whoMadeCoffee.resize(2);
pNico = nullptr;

"Nico"关联的内存确实被删除。

有人可以解释一下区别吗?

1 个答案:

答案 0 :(得分:4)

  

在程序结束时,字符串的最后一个所有者   销毁后,共享指针将为其引用的对象调用delete   至。这种删除不必不必要在最后完成   范围。

{{ (sender.firstName or sender.lastName ? "<strong>#{sender.firstName} #{sender.lastName}</strong>" : "<strong>Unknown</strong>")|raw }} 将在引用计数达到0时被销毁。在您的示例中,对于Nico,引用计数达到0(甚至在到达作用域末尾之前)。

如果您与当前范围之外的其他人共享,例如它具有返回string("Nico")的函数,或者它是一个更简单的示例,则它可能超出其范围:

shared_ptr

godbolt上直播