【发布时间】:2015-05-18 03:20:42
【问题描述】:
我从 C++ Primer 5 Edition 中读取了智能指针。在第 12.1.3 节中,一些描述类似于
智能指针类型定义了一个名为“get”的函数,它返回一个指向智能指针所管理对象的内置指针。该函数适用于我们需要将内置指针传递给无法使用智能指针的代码的情况。 使用“get”返回的代码不得“删除”该指针。
描述下面也给出了一个例子
shared_ptr<int> p(new int(42)); // reference count is 1
int *q = p.get();
{//new block
//undefined:two independent shared_ptr point to the same memory
shared_ptr<int>(q);
}//block ends, q is destroyed ,and the memory to which q points is freed
int foo = *q; //undefined; the memory to which p points was freed
我可以清楚地理解上面的解释。 但是,当我遇到 Exercise 12.13 时,我有点困惑。
#include<iostream>
#include<memory>
using namespace std;
int main(){
auto sp = make_shared<int>();
auto p = sp.get();
delete p;
cout <<"Before main function exits!"<<endl; //which I add for debug
return 0;
}
编译没有错误。但是运行时出现如下错误
***Error in './ex12_13': double free or corruption(out): 0x09b97018***
以及要调试的上下文 在主函数退出之前! 尚未执行,这意味着错误发生在delete之后 操作在我看来。我也使用 'gdb' 调试这个程序,确实在 delete 之后弹出错误。
那么,如何解释错误? Delete 已经释放了内存,但第二次释放何时发生?在 main 函数退出之前?
我将 sp 的初始化从 make_shared 函数更改为 new 和 使用我自己的 deleter 函数代替 delete。
#include<iostream>
#include<memory>
using namespace std;
int main(){
auto deleter = [](int*p){
cout<<"deleter called"<<endl; delete p;
};
shared_ptr<int> sp(new int, deleter);
auto p = sp.get();
delete p;
cout <<"Before main function exits!"<<endl; //which I add for debug
return 0;
}
然后输出结果是
Before main function exits!
deleter called
***Error in './ex12_13_2': double free or corruption(out): 0x08995998***
当程序超出主作用域时,局部变量shared_ptr p将被销毁,p指向的内存将被调用deleter。
这就是为什么“before main function exits!”首先显示,deleter called稍后显示,最后出现double free错误。
所以我认为我上面提出的困惑主要是来自make_shared。 @Ben Voigt 给出了详细的解释。
您正在删除一个不是来自 new 的指针,因此您有未定义的行为(任何事情都可能发生)。
但深层原因可能只能从make_shared的实现中找到。
【问题讨论】:
-
我在这里遇到另一个错误 -- ideone.com/eMJMOJ
-
@Diego 您提到的错误在我的 g++ 编译器上没有发生,在这个在线编译器上也没有发生 [link]coliru.stacked-crooked.com
标签: c++ pointers shared-ptr smart-pointers