为什么这个共享指针的赋值在从嵌套函数返回后没有效果?

Why did this assignment of a shared pointer have no effect after returning from nested function?

考虑这个 mwe:

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

using namespace std;

struct A {
    shared_ptr<vector<int>> b;
};

void foo(vector<A> &vec)
{
    auto c = shared_ptr<vector<int>>(new vector<int>{42});
    vec.back().b = c;
    cout << "Foo size " << vec.back().b->size() << endl;
}

void bar(A &a)
{
    auto vec = vector<A>{a};
    foo(vec);
}


int main()
{
    A a;
    bar(a);
    cout << "Main size" << a.b->size() << endl;
    return 0;
}

这是程序的输出:

~ ./a.out                
Foo size 1
[1]    107400 segmentation fault (core dumped)  ./a.out

为什么 a.b->size() 产生段错误,而不是让包含 42 的向量报告其大小?

背景:我对C++只有很肤浅的了解。通常我在 Python 中编程,但最近(几周前)我开始研究别人的 C++ 代码库并向其添加一些功能。

std::vector 和其他标准容器始终存储对象的副本。

当您执行 auto vec = vector<A>{a}; 时,a 被复制到矢量中,因此对矢量的任何更改都不会影响 a

main() 中,a.b 没有指向有效的 vector,因此访问 a.b->size()未定义的行为 .

bar() 创建一个新的 vector,其中包含传入的 A 对象的 副本 foo() 然后作用于 复制的 A 对象,而不是 main().

中的原始 A 对象

如果您希望 foo() 作用于 main() 中的原始 A 对象,则必须更改 bar() 以传递 vector<A*>foo(),例如:

#include <iostream>
#include <memory>
#include <vector>
using namespace std;

struct A {
    shared_ptr<vector<int>> b;
};

void foo(vector<A*> &vec)
{
    auto c = shared_ptr<vector<int>>(new vector<int>{42});
    vec.back()->b = c;
    cout << "Foo size " << vec.back()->b->size() << endl;
}

void bar(A &a)
{
    auto vec = vector<A*>{&a};
    foo(vec);
}

int main()
{
    A a;
    bar(a);
    cout << "Main size" << a.b->size() << endl;
    return 0;
}