如何将shared_ptr与指向不应释放的结构的指针一起使用
How to use a shared_ptr with a pointer to struct that should not be freed
目前我正在使用glib库中的一些函数。油嘴滑舌的还有焦音。glib是一个C库,因此我需要删除我创建的一些结构。
对于许多对象,我创建了一个智能指针,例如:
std::shared_ptr<GAsyncQueue> my_queue = std::shared_ptr<GAsyncQueue>(g_async_queue_create(), g_async_queue_unref);
因为这会创建一个指向GAsyncQueue
的共享指针,并且在队列寿命结束时安全地销毁队列。
然而,当我从gio库获得一个指针时,我遇到了一个问题,我不应该释放它。在下面的代码中,my_connection
是一个GSocketClient,它实现(用glib语言)GIOStream。
std::shared_ptr<GInputStream> my_input_stream =
std::shared_ptr<GInputStream> (
g_io_stream_get_input_stream(G_IO_STREAM(my_connection.get()))
);
因为GIOStream上的文档提到,使用g_io_stream_get_input_stream()
获得的指针不应该被释放。这是因为它由my_connection
实例所有。我考虑为destroy对象创建一个lamda,这是共享指针对象的第二个参数。例如auto deleter = [](GInputStream* ptr) {};
,然后将lambda作为destroy函数提供给共享指针,但这感觉有点愚蠢。
好吧,没有操作删除程序的替代方案可能是使用别名共享指针
template <class U> shared_ptr (const shared_ptr<U>& x, element_type* p) noexcept;
它共享x
,但在get()之后,您将返回p
。
讨论:什么是shared_ptr';的别名构造函数?
您可能不需要std::shared_ptr
。而且你可能根本不需要指针。
当我读到你的问题和评论时,我看不出有任何反对的观点
auto& my_input_stream = *( g_io_stream_get_input_stream(G_IO_STREAM(my_connection.get())) )
指针确实允许使用可选数据。然而,它的使用方式大多是错误的,这也是事实。具有
void foo( type* ptr)
{
if (!ptr)
throw exception;
}
通常没有意义。如果函数必须处理具体的数据,那么只有当您担心提供数据时,允许NULL参数才有用。否则,只需要对对象进行引用(可能是const
)。
智能指针很有用;但它们仍然是指针。如果可能的话,完全避免它们会更好。
来自评论:
但是,引用必须始终初始化
当然。从C++11开始,我们有了std::reference_wrapper
,它也可以重新连接并存储在容器中。
您可以使用一个什么都不做的deleter类型,但它需要作为参数传递给shared_ptr
的构造函数
struct DoNothing {
template <typename T>
void operator()(T*) const noexcept { }
};
创建shared_ptr
时,您需要创建其中一个deleter,并将其传递给构造函数(就像您对lambda所做的那样)。你可以通过一个中间功能让这件事变得更容易
template <typename T>
std::shared_ptr<T> non_deleting_shared_ptr(T* ptr) {
return {ptr, DoNothing};
}
auto my_input_stream =
non_deleting_shared_ptr(
g_io_stream_get_input_stream(G_IO_STREAM(my_connection.get()));
然而,更大的问题是,当你不想所有权成为智能指针的一部分时,为什么你要使用智能指针。几乎可以肯定,只有GAsyncQueue*
会更好,当然,除非你的shared_ptr
有时需要释放。也许像一个数据成员?
- 为什么这个 std::queue/指向结构的指针列表直到 List.Size() == 0 才释放内存?
- 包含矢量指针的结构的内存释放问题
- 如何安全地停止 IOCP WSARecv() 任务,并释放 WSAOVERLAPED 结构?
- 我可以使用哪种数据结构来释放连续内存中的内存?
- 释放包含多个向量的结构的内存
- 释放指向保留嵌套变量内存地址的结构的指针
- C++:释放动态数组(结构成员)和指向此结构的指针的方法
- std::unordered_map 如何释放使用 malloc 创建的结构.是否需要对地图进行 2 次查询
- 数据结构中的双重释放或损坏
- 用C++11中的智能指针包装旧的C结构并自动释放它们
- 释放包含STL类的链接列表结构的内存
- 如何在C++中释放结构和对象的数组
- C++在结构初始化后释放内存
- 释放组合结构内存的正确方法
- wlanapi-将WlanFreeMemory释放其WLAN_INTERFACE_INFO数组结构
- C++释放结构使用的所有内存
- 释放包含恶意字符串的 malloc'd 结构
- 如何将shared_ptr与指向不应释放的结构的指针一起使用
- 如何从 Libxml2 库中释放结构 xmlSAXHandler
- 如何释放一个结构体的内存,每次循环迭代的指针