为何shared_ptr存储的对象地址与原对象不同?如何修改其存储对象?
你确实误解了shared_ptr的核心行为:shared_ptr并不存储原始对象本身,它是一个智能指针,负责管理动态分配(堆上)对象的生命周期。它内部持有的是指向目标对象的指针,而非对象的拷贝。
你的代码里出现多个对象地址不同的情况,大概率是这两个原因:
- 初始化shared_ptr时创建了对象拷贝,比如用
make_shared<A>(a)把栈对象a复制到堆上,此时shared_ptr指向的是全新的堆对象,自然和原始栈对象a地址不同;如果b.a_也是用类似方式初始化,它指向的又是另一个独立的堆对象,最终三个地址完全不重合。 - 多个shared_ptr没有指向同一个动态对象,各自持有独立的实例,所以修改其中一个不会影响其他对象。
要修改shared_ptr管理的对象的值,同时让所有指向该对象的shared_ptr看到变化,你需要:
- 确保所有shared_ptr指向同一个动态分配的对象:
- 用
make_shared创建堆对象,再赋值给多个shared_ptr:auto sa = std::make_shared<A>(); std::shared_ptr<A> sa2 = sa; // sa和sa2指向同一个堆对象 - 或者基于已有的shared_ptr创建新实例(不推荐直接用原始堆指针初始化多个shared_ptr,容易触发重复释放)。
- 用
- 通过shared_ptr访问并修改对象:
- 用解引用操作符
*获取对象引用后修改:(*sa).a = 10; - 用箭头操作符
->直接访问成员:sa->a = 10;
- 用解引用操作符
正确示例:
#include <memory> #include <iostream> struct A { int a = 0; }; struct B { std::shared_ptr<A> a_; }; int main() { // 创建堆上的A对象,由sa管理 auto sa = std::make_shared<A>(); sa->a = 5; B b; b.a_ = sa; // b.a_与sa指向同一对象 // 修改b.a_指向的对象值 b.a_->a = 10; // sa指向的对象值同步变为10 std::cout << sa->a << std::endl; // 输出10 }
注意:绝对不要用栈对象的地址初始化shared_ptr(比如std::shared_ptr<A> sa(&a);),这会导致shared_ptr析构时尝试delete栈内存,触发未定义行为,大概率导致程序崩溃。
内容的提问来源于stack exchange,提问作者LunaticJape
相关产品推荐
相关产品推荐

