使用从 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" 的语句删除,但对象保持不变并打印在输出语句中。

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