跟踪向量中的智能指针

Keep track of smart pointer in vector

std::vector<unique_ptr<int>> v;
v.push_back(std::make_unique<int>(1));

unique_ptr<int>& rp0 = v[0];
cout << "rp1="<<rp0.get()<<"\n";
cout << "*rp1="<<*rp0<<"\n";

v.push_back(std::make_unique<int>(2));

cout << "rp1="<<rp0.get()<<"\n";
cout << "*rp1="<<*rp0<<"\n";

为什么第二次打印的结果和第一次不一样?

rp1=0x1783c20
*rp1=1
rp1=0
Segmentation fault (core dumped)

根据:https://en.cppreference.com/w/cpp/container/vector/push_back 我引用:

If the new size() is greater than capacity() then all iterators and references (including the past-the-end iterator) are invalidated. Otherwise only the past-the-end iterator is invalidated.

所以基本上在执行 push_back 时,如果需要,向量会创建一个更大容量的新缓冲区,将所有 std::unique_ptr 从旧缓冲区移动到新缓冲区,添加新的 unique_ptr 并删除旧缓冲区。

您有对旧缓冲区中悬垂元素的引用。悬空引用是未定义的行为,一切都可能发生,例如,您可能会打印垃圾数据或崩溃。

编辑: 我解释了这个问题,Oblivion 在他们的回答中解释了使用 shared_ptr 可能适合或不适合的用例的可能补救措施未知。

@CuriouslyRecurringThoughts 详细解释了为什么你有悬空引用,我只是给出一个可能的解决方案。

在您的示例中避免悬空引用的一种方法是使用 shared_ptr 而不是对 unique_ptr 的引用:

#include<iostream>
#include <vector>
#include <memory>

int main()
{
    std::vector<std::shared_ptr<int>> v;
    v.push_back(std::make_shared<int>(1));

    std::shared_ptr<int> rp0 = v[0];
    std::cout << "rp1="<<rp0.get()<<"\n";
    std::cout << "*rp1="<<*rp0<<"\n";

    v.push_back(std::make_shared<int>(2));

    std::cout << "rp1="<<rp0.get()<<"\n";
    std::cout << "*rp1="<<*rp0<<"\n";
}

Live