c++ shared_ptr和内置指针

C++ shared_ptr and built-in pointer

本文关键字:内置 指针 ptr shared c++      更新时间:2023-10-16

删除两次内置指针导致未定义,但是在这种情况下会发生什么?在这段代码中,共享指针是否未定义?

string *str_1 = new string;
std::shared_ptr<string> str_ptr(str_1);
*str_1 = "C++";
cout << *str_ptr << endl;
*str_ptr = "C#";
cout << *str_1 << endl;
// str_1 & str_ptr refers same piece of memory    
delete str_1;
cout << *str_ptr << endl;  // Is this undefined?

你的代码是未定义的,因为在调用删除原始指针之后,shared_ptr留下了一个悬空指针引用。然后你继续解引用已经释放的内存(未定义的行为1)。当shared_ptr超出作用域时,它将在被告知要管理的指针上调用delete,这将释放已经释放的内存(未定义的行为2)。

为方便起见,shared_ptr允许从原始指针初始化,但是您应该允许它在之后管理分配的内存。这是一个错误来管理原始指针(例如,删除它或初始化另一个shared_ptr),当你把它给shared_ptr

在使用shared_ptr时使用辅助函数make_shared实际上是更好的实践。

std::shared_ptr<std::string> sp = std::make_shared<std::string>("C++");

这种格式避免了创建原始指针的问题。它还被证明是更有效的,因为它避免了智能指针在传递原始指针时必须做的额外分配。

sharped_ptr不是魔法。一旦对象的最后一个shared_ptr被销毁,它就简单地调用delete。因此,代码调用delete两次,一次是在删除str_1时,一次是在str_ptr超出作用域时。因此,与显式调用delete两次相比,使用shared_ptr不会改变任何东西:结果是未定义的行为。

shared_ptr的发明是为了从你那里承担显式delete调用的负担。因此,也没有理由同时使用shared_ptr 显式delete。所以即使它没有导致未定义的行为,我的建议仍然是:不要这样做!