shared_ptr的机制

时间:2017-05-15 10:32:55

标签: c++ pointers shared-ptr

我在C ++上偶然发现了这个问题,但完全不知道它是怎么发生的,请查看下面的代码片段:

    int main() {
        int *aptr = new int(20); //Declare an integer space with 20, and aptr points to it
        shared_ptr<int> a(aptr); //Declare a shared_ptr to points where aptr points

        stringstream ss;
        ss << a;
        const char *chstr = ss.str().c_str();  // Save the address as string

        void *address;
        sscanf(chstr, "%p", (void **)&address); // Convert string back to pointer

        a = NULL;  // Free the shared pointer   
        cout << *reinterpret_cast<int*>(address) << endl; // Output: 0, 20 has gone

        return 0;
}

有没有人可以告诉我为什么地址已被释放?
我没有操纵原始的整数指针“aptr”,但是因为shared_ptr,所以它的空间已经消失了。 我想知道它是怎么发生的,谢谢大家!

2 个答案:

答案 0 :(得分:7)

A        1.48        2.64    1.02         2.46   2.73 C        3.76         2.07    4.61         2.26   2.05 背后的全部目的是取得动态分配对象的所有权。一旦std::shared_ptr获得动态分配的对象的所有权,通过std::shared_ptr或直接指定它,std::make_shared拥有它,锁定库存和桶。拥有它意味着当对动态范围对象的最后一次引用超出范围时,自动std::shared_ptr动态范围对象。这就是delete的用途,而不是别的。

shared_ptr

这使用a = NULL; 的赋值运算符来替换shared_ptr拥有的指针(*)。由于shared_ptr拥有的原始动态范围对象没有其他引用,shared_ptr shared_ptr是用于构造它的原始指针。

您仍然拥有指向delete的原始本机指针这一事实无关紧要。 int并不关心。整件事情得到shared_ptr d。

如果您不希望delete shared_ptr delete new,并使用原生指针,请不要使用shared_ptr,或确保只要你仍然需要使用指向底层对象的本机指针,一个仍然存在。

(*)这实际上隐含地构造了另一个shared_ptr,并使用了常规赋值运算符。

答案 1 :(得分:1)

此代码无法在g ++ 4.2.1中编译(但正如Sam所提到的,它符合版本6):

Georgioss-MacBook-Pro:~ gsamaras$ g++ -Wall main.cpp 
main.cpp:17:11: error: no viable overloaded '='
        a = NULL;  // Free the shared pointer   
        ~ ^ ~~~~

顺便说一句,你应该使用shared_ptr::reset

  

在所有其他情况下,shared_ptr通过use获取p的所有权   计数为1,并且 - 最后 - 使用del和/或alloc作为删除和   分配器。

     

此外,对此功能的调用具有相同的副作用   shared_ptr的析构函数在其值更改之前被调用(包括   如果此shared_ptr是唯一的,则删除托管对象。

同时检查string::c_str。您正在保存临时字符串的地址,这是不好的开始。