修改后为什么共享指针无效?

时间:2016-02-05 19:59:43

标签: c++ shared-ptr

根据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吗?另一方面,如果由vector导致share_ptr上的许多操作无法应用,那么会不方便吗?

阅读完评论后,我现在开始明白它的真正含义。 shared_ptr的修改使指向它的其他原始指针无效。

正如dyp在评论中指出的那样,push_back可能会重新分配,这可能会使ptr无效。如果它没有重新分配,ptr是否仍然有效?如果它确实重新分配,如果编译器只是将所有伙伴带到新的区域,比如说,将这些原始指针分配给新地址,那么它是否会更简单,更具建设性?

1 个答案:

答案 0 :(得分:0)

在更大的背景下,Herb在2015年CPPCon上为Guidelines Support Library做广告(他不是唯一一个)。

他试图提出的一点是,根据标准存在完全合法的代码,但通过静态分析,我们可以判断它是有问题的。

在这里给出的示例中,我们有shared_ptrvector,然后是指向该指针的原始指针,然后是指向共享指针所持有的向量的原始指针,甚至指向共享指针内保存的向量内的元素的原始指针。

然后他做了很多会导致未定义行为的事情。调用是完全合法的(在shared_ptr上调用重置然后尝试对vector执行操作)但是在更大的上下文中,他认为编译器应该能告诉你(通过静态分析)你做了一件坏事。

所以在视频中你看到他做了这些不会被现代编译器捕获的坏东西,然后演示了如何使用GSL 的编译器(在本例中为Visual Studio 2015)将捕获它们。

这次谈话同样具有政治性,因为它提供了丰富的信息。可能因为Herb本人是微软员工而使用Visual Studio。这不一定是坏事;人们普遍认为,Visual Studio是一个很棒的IDE,而且我认为要消除的信息是微软确实致力于C ++,尽管近年来有很多举措表明C#可能有更高的承诺,让C ++开发人员感觉像是二等公民。