使用从 std::shared_ptr<T>.get() 函数返回的指针来删除对象?
Using the pointer returned from a std::shared_ptr<T>.get() function to delete an object?
int main(int argc, char *argv[])
{
auto sp = std::make_shared<int>();
auto p = sp.get();
delete p; //here
std::cout << *sp << std::endl;
return 0;
}
我希望 shared_ptr sp
管理的对象将被注释 "here" 的语句删除,但对象保持不变并打印在输出语句中。
- 这行不通是不是因为我没有用
new
关键字显式创建由shared_ptr
管理的对象(因为每个new
语句必须有对应的delete
语句,因此每个 delete
语句,一个较早的对应 new
关键字?)?
- 这是否意味着由
shared_ptr
s 管理、从 make_shared
函数创建的指向对象仅由 shared_ptr
s 本身销毁?
shared_ptr
不认识你 delete
你从 .get()
得到的指针。因此,当 shared_ptr
本身被销毁时,它会 也 尝试 删除 对象 - 导致双重删除 undefined behaviour.此外,取消引用指向已删除对象的指针也是 also UB。
delete
将对象占用的内存标记为"free to be re-used",并调用对象的析构函数。在 delete
之后,您将不允许(在调用 UB 的痛苦下)再次访问该对象。
您的程序完全无效,编译器可能生成的任何内容都是允许的。
首先,如果你这样做,你的对象将被删除两次,如果你幸运的话,你会崩溃。
其次,仅仅因为某些内容已被删除并不意味着它的基础表示肯定是无效的。您可能会遇到内存被释放的情况,但还没有任何东西可以覆盖之前的内存。
"manage" 与 shared_ptr
关联的内存的方法是使用 C++ 作用域,通常称为 RAII (Resource A获取Is I初始化).
对于您的代码:
int main(int argc, char *argv[])
{
{
auto sp = std::make_shared<int>();
std::cout << *sp << std::endl;
}
// memory is now delete'd because "sp" is out-of-scope
return 0;
}
对于 shared_ptr
,事情实际上可能(相当多)比这更复杂,因为多个 shared_ptr
可以指向同一个内存;只有当 last 一个消失时,内存才会被删除。
您应该优先使用 std::unique_ptr
,直到您真正需要 shared_ptr
。
int main(int argc, char *argv[])
{
auto sp = std::make_shared<int>();
auto p = sp.get();
delete p; //here
std::cout << *sp << std::endl;
return 0;
}
我希望 shared_ptr sp
管理的对象将被注释 "here" 的语句删除,但对象保持不变并打印在输出语句中。
- 这行不通是不是因为我没有用
new
关键字显式创建由shared_ptr
管理的对象(因为每个new
语句必须有对应的delete
语句,因此每个delete
语句,一个较早的对应new
关键字?)? - 这是否意味着由
shared_ptr
s 管理、从make_shared
函数创建的指向对象仅由shared_ptr
s 本身销毁?
shared_ptr
不认识你 delete
你从 .get()
得到的指针。因此,当 shared_ptr
本身被销毁时,它会 也 尝试 删除 对象 - 导致双重删除 undefined behaviour.此外,取消引用指向已删除对象的指针也是 also UB。
delete
将对象占用的内存标记为"free to be re-used",并调用对象的析构函数。在 delete
之后,您将不允许(在调用 UB 的痛苦下)再次访问该对象。
您的程序完全无效,编译器可能生成的任何内容都是允许的。
首先,如果你这样做,你的对象将被删除两次,如果你幸运的话,你会崩溃。
其次,仅仅因为某些内容已被删除并不意味着它的基础表示肯定是无效的。您可能会遇到内存被释放的情况,但还没有任何东西可以覆盖之前的内存。
"manage" 与 shared_ptr
关联的内存的方法是使用 C++ 作用域,通常称为 RAII (Resource A获取Is I初始化).
对于您的代码:
int main(int argc, char *argv[])
{
{
auto sp = std::make_shared<int>();
std::cout << *sp << std::endl;
}
// memory is now delete'd because "sp" is out-of-scope
return 0;
}
对于 shared_ptr
,事情实际上可能(相当多)比这更复杂,因为多个 shared_ptr
可以指向同一个内存;只有当 last 一个消失时,内存才会被删除。
您应该优先使用 std::unique_ptr
,直到您真正需要 shared_ptr
。