假设我有以下代码:
#include <memory>
struct Foo{};
int main()
{
std::shared_ptr<Foo> pf = std::make_shared<Foo>();
delete pf.get();
//do anything else
return 0;
}
为什么我不能使用delete
直接删除Foo
对象?
在我看来,问题在于智能指针被破坏之后,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)...);
}
答案 0 :(得分:2)
正确的解释是您没有通过new
获取指针,因此对其调用delete
是未定义的行为,并且编译器可以执行所需的任何操作。
您甚至不应该思考。
实现详细信息答案(如有更改,恕不另行通知,编译器版本甚至编译开关之间的结果可能会有所不同)是make_shared
一次分配引用计数控制块和对象,然后为您提供指向此分配的指针。由于通常会在对象之前 分配控制块,因此这意味着您传递给delete
的内存地址不是从内存分配器返回的地址。