c++ shared_ptr和内置指针
C++ shared_ptr and built-in pointer
删除两次内置指针导致未定义,但是在这种情况下会发生什么?在这段代码中,共享指针是否未定义?
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
。所以即使它没有导致未定义的行为,我的建议仍然是:不要这样做!
相关文章:
- 内置函数可查看CPP中的成员变量
- 是否有内置方法可以强制转换为不同的基础类型,但保留常量限定符?
- 按字母顺序对字符串中的字母进行排序,而无需使用内置的 sort()
- 将字符串转换为浮点数或整数,而无需使用内置函数(如 atoi 或 atof)
- 如何从 c++ 中类中内置的数组继承
- 如何捕获 C++ 内置异常对象
- macOS 是内置在 clang 编译器中还是内置于 xcode ide 中?
- 将编译器开关添加到 Eclipse CDT 内置编译器设置生成?
- gcc Atomic在gcc 4.1.1中内置了奇怪的行为
- 是否有用于元素部分移位的 simd 指令/内在/内置指令?
- 何时包含内置类型和运算符的标头?
- 基本类型与内置类型有什么区别C++
- 指内置类型的文字
- GLUT 问题:重新声明 c++ 内置类型'wchar_t'时出错
- 像自定义类一样构造的指针(内置类型)如何工作?
- 使用C RTTI(内置)通过字符串查找功能指针
- 为什么指针类型的内置关系运算符不生成C++的总顺序?
- 将指针传递给在 C++ 中动态定义的内置类型
- 是否可以获取内置标准运算符的函数指针
- c++ shared_ptr和内置指针