c++11 - 为什么在“delete shared_ptr::get()”中使用时删除会触发错误
问题描述
假设我有以下代码:
#include <memory>
struct Foo{};
int main()
{
std::shared_ptr<Foo> pf = std::make_shared<Foo>();
delete pf.get();
//do anything else
return 0;
}
为什么我不能delete
直接使用deleteFoo
对象?在我看来,问题是智能指针析构后,delete
会被调用两次,导致未定义的行为。但是为什么我第一次手动使用时会触发错误. 我很困惑,请帮助我。
而且我发现在visual studio中的返回值和真实对象的get()
分配地址是一样的。如下:Foo
new
template<class... _Types>
explicit _Ref_count_obj(_Types&&... _Args)
: _Ref_count_base()
{ // construct from argument list
::new (static_cast<void *>(&_Storage)) _Ty(_STD forward<_Types>(_Args)...);
}
解决方案
正确的解释是你没有通过 获得指针new
,因此调用delete
它是未定义的行为,编译器可以做任何它想做的事情。
你甚至不应该超越这一点。
实现细节答案(如有更改,恕不另行通知,编译器版本甚至编译开关之间的结果可能会有所不同)是make_shared
在单个分配中分配引用计数控制块和对象,然后为您提供指向此分配的指针。由于控制块通常会在对象之前分配,这意味着您交给的内存地址delete
不是从内存分配器返回的地址。
推荐阅读
- macos - Intellij IDEA 使用哪个 java 路径进行 gradle 测试?
- ios - 如何在不删除数据的情况下更改捆绑 ID
- php - 替换函数不适用于 bind_param
- python - 与 Dataframe 列(多于一列)的列表比较列表
- java - 为什么我的 Java 计时器程序无法在 Mac 上运行?
- c# - Dot Net Core Mongo Health Check ERROR: New MongoClient can't be added into dictionary
- machine-learning - 使用当前无效的输入数据进行预测
- heroku - 从 Strapi 获取数据,将 gatsby 应用程序部署到 netlify
- m2doc - M2DOC如何自定义Table
- python - 将 colmap 与 GPU 一起使用,但 Docker 容器内没有附加显示