C ++ shared_ptr和内置指针

时间:2014-08-05 16:04:39

标签: c++ pointers shared-ptr

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

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?

2 个答案:

答案 0 :(得分:3)

您的代码未定义,因为在调用删除原始指针后,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++");

此格式避免了您必须处理创建原始指针。事实证明它更有效,因为它避免了智能指针在传递原始指针时必须进行的额外分配。

答案 1 :(得分:2)

sharped_ptr不是魔法。一旦对象的最后delete被销毁,它就会调用shared_ptr。因此,代码调用delete两次,一次删除str_1,然后str_ptr超出范围。因此,使用shared_ptr与显式调用delete相比没有任何改变:结果是未定义的行为。

shared_ptr的发明是为了承担你明确的delete电话的负担。因此,也没有理由将shared_ptr 显式delete结合使用。因此,即使它没有导致未定义的行为,我的建议仍然是:不要这样做!