跟踪向量中的智能指针
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";
}
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";
}