为什么共享指针在修改后要失效
Why should a shared pointer be invalidated after modification?
根据Herb Sutter在CppCon 2015上的演讲,修改后shared_ptr
应该无效,
auto sv = make_shared<vector<int>>(100);
shared_ptr<vector<int>>* sv2 = &sv;
vector<int>* vec = &*sv;
int* ptr = &(*sv)[0];
*ptr = 1 ;
vec->push_back(2); //A: modification
*ptr = 5; //Error: ptr was invalidated by "push_back" on line A
ptr = &(*sv)[0];
(*sv2).reset(); //B: modification
vec->push_back(6); //Error: vec was invalidated by "reset" on line B
我的编译器没有捕获这些错误。无论如何,我们使用智能指针来防止内存泄漏。抑制shared_ptr
修改的原因是什么?为了避免意外?如果是这样的话,我们不能直接宣布它const
吗?另一方面,如果由于share_ptr
而无法对vector
进行许多操作,那会不会很不方便?
看完评论后,现在我开始明白它在这里到底做了什么。对shared_ptr
的修改会使指向它的其他原始指针无效。
正如dyp在评论中指出的那样,push_back
可能会重新分配,这可能会使ptr
无效。如果它没有重新分配,ptr
是否仍然有效?如果它确实重新分配,如果编译器只是将其所有伙伴带到新领域,例如,为这些原始指针分配新地址,那不是更简单、更有建设性吗?
在更大的背景下,赫伯在CPPCon 2015上为指南支持图书馆做广告(他不是唯一一个(。
他试图表达的观点是,根据标准,存在完全合法的代码,但通过静态分析,我们可以说它是有问题的。
在这里给出的示例中,我们有一个指向vector
的shared_ptr
,然后是一个指向该指针的原始指针,然后是一个指向共享指针所持有的向量的原始指针,甚至还有一个指向共享指针内持有的向量中持有的元素的原始指针。
然后他做了一堆会导致不确定行为的事情。这些调用是完全合法的(在shared_ptr
上调用重置,然后尝试在vector
上执行操作(,但是在更大的背景下,他认为编译器应该能够告诉你(通过静态分析(你做了一件坏事。
所以在视频中,你会看到他做了这些现代编译器无法捕捉到的坏事,然后演示了充满GSL的编译器(在本例中为Visual Studio 2015(如何捕捉它们。
这次谈话既具有政治性,又内容丰富。使用Visual Studio可能是因为Herb本人是Microsoft员工。这不一定是一件坏事;人们普遍认为Visual Studio是一个伟大的IDE,我认为要传达的信息是,Microsoft确实致力于C++,尽管近年来的许多举措表明了对C#的更高承诺,这让C++开发人员感觉自己是二等公民。
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 独立读取-修改-写入顺序
- 当系统的卷被修改时,如何修改WASAPI环回捕获卷
- 修改函数中的指针(将另一个指针作为参数传递)
- 为什么我可以通过引用修改常量返回
- 对于结构,表达式必须是可修改的ivalue
- QML:修改在不同QML文件(而非main.QML)中定义的子对象的属性
- 为什么不能修改对象中的值?另外,我如何改进此链表?
- 修改创建帐户程序
- 我应该如何修改此代码以使用给定字符串中的字母打印菱形图案
- 如何从子成员函数修改父公共成员变量
- 修改 VS Code 中的默认C++代码段
- 为什么在我的函数类型后使用引用运算符 (&) 允许我修改它返回的值?
- 如何使用递归打印修改后的星号三角形图案
- 已修改的LinkedList未在文本文件本身中更新
- 不明白迭代器,引用和指针失效,一个例子
- C++RapidXml-使用first_node()遍历以修改XML文件中节点的值
- 为什么可以修改数组 b?
- 将 C++ 类与 Rcpp 一起使用,从 C 或 R 修改它
- 为什么共享指针在修改后要失效