使shared_ptr失去对内存的所有权
Making shared_ptr lose ownership of memory
我有一个shared_ptr<MyProto>
,我把它传来传去。最终,在某些情况下,我希望将原始指针传递给一个函数,该函数随后成为内存所有者。在这些情况下,shared_ptr
不再负责释放内存,因为我调用的函数获得了所有权。如何让shared_ptr
失去所有权?
我想让shared_ptr
失去所有权的原因是我想使用协议缓冲区的 AddAssigned 功能,该功能采用已分配的指针并承担其所有权。
例:
shared_ptr<MyProto> myProtoSharedPtr = // by this point this is the last reference to the heap allocated MyProto
// I want to add it to a collection and serialize the collection without copying
CollectionProto collectionProto;
collectionProto.mutable_my_proto().AddAllocated(myProtoSharedPtr.get()); // at this point collectionProto took ownership of the memory
std::string serialization = collectionProto.SerializeAsString();
// bad: myProtoSharedPtr.get() will be freed twice
我认为您可以通过分享独特的 像这样的指针:
std::shared_ptr<std::unique_ptr<MyProto>> myProtoSharedUniquePtr;
访问它会更间接:
(*myProtoSharedUniquePtr)->do_stuff();
但是你可以像这样获得所有权:
CollectionProto collectionProto;
collectionProto.mutable_my_proto().AddAllocated(myProtoSharedUniquePtr->release()); // at this point collectionProto took ownership of the memory
std::string serialization = collectionProto.SerializeAsString();
但是,我会质疑您为什么要开始使用std::shared_ptr
。使用std::shared_ptr
的原因是当您无法控制谁将最后一个访问它时,因此每个人都可以保持其活动状态,直到他们完成。因此,能够保证不再使用所有当前std::shared_ptr
实例是不寻常的。
您确定std::unique_ptr
不会更适合您的需求吗?
您可以使用unique_ptr
,无论如何,它更适合传递内存:
unique_ptr<MyProto> myProtoSharedPtr = // create MyPorto object
CollectionProto collectionProto;
// unique_ptr::release returns the pointer and
// releases the ownership of the MyProto object
collectionProto.mutable_my_proto().AddAllocated(myProtoSharedPtr.release());
std::string serialization = collectionProto.SerializeAsString();
您需要为std::shared_ptr
提供自定义删除器(请参阅构造函数 4(。然后,您可以定义删除程序以执行所需的操作。包括,而不是破坏您的对象。
注意1:我不建议在这里使用shared_ptr,但这是一种做你想做的事的方法。
注意 2:如果使用make_shared
创建对象,则在删除最后一个shared_ptr后,在正确删除内存时可能会遇到问题。
与其复制,不如将其移动到new
ed 对象中。
MyProto * myProto = new MyProto(std::move(*mySharedProto));
CollectionProto collectionProto;
collectionProto.mutable_my_proto().AddAllocated(myProto);
您还可以调查CollectionProto
是否会按值接受它
CollectionProto collectionProto;
collectionProto.mutable_my_proto().Add(std::move(*mySharedProto));
当您想要转让所有权时,可以使用 std::move,请参阅以下示例
#include <iostream>
#include <memory>
void take_ownership(std::shared_ptr<int> ptr){
std::cout<<ptr.use_count()<<" == 2n";
} // destroying it
int main()
{
std::shared_ptr<int> p=std::make_shared<int>(1);
std::shared_ptr<int> p2(p);
//p is valid
if(!p.get())
std::cout<<"errorn";
else
std::cout<<"OKn";
//use p, p2
take_ownership(std::move(p));
//p is invalid
if(!p.get())
std::cout<<"OKn";
else
std::cout<<p.use_count()<<" errorn";
}
- 将字符串存储在c++中的稳定内存中
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- Win32编译器选项和内存分配
- 当vector是tje全局变量时,c++中vector的内存管理
- 带内存和隔离功能的SQLite
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 迭代时从向量和内存中删除对象
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 为什么示例代码访问IUnknown中已删除的内存
- 如何在C++类内存结构中创建"spacer"?
- Qt对象所有权内存泄漏
- 使shared_ptr失去对内存的所有权
- 给出一个 std::vector 对另一个向量的内存的所有权?
- 使用PYBIND11,如何为Array_t对象设置基础内存的所有权
- 如何从eigen :: matrix获取内存所有权
- 从 Qt 类派生的用户定义类中的内存所有权
- MSXML方法是否对其BSTR参数拥有内存所有权?
- 从C#COM方法返回对象和内存所有权