【问题标题】:When a unique_ptr is deallocated?何时释放 unique_ptr?
【发布时间】:2020-02-02 16:45:59
【问题描述】:

在这段代码中:

void f(std::unique_ptr<int> q)
{
}

void g()
{
    std::unique_ptr<int> p{new int{42}};
    f(std::move(p));
}

在哪一行 p 被释放?我会在 f 函数的出口处说,因为它是使用 std::move 移动到那里的,但我不确定也不确定这个答案。

【问题讨论】:

    标签: c++ c++11 memory-management smart-pointers unique-ptr


    【解决方案1】:

    p 在哪一行被释放?

    在声明它的范围的末尾,即在这种情况下的函数 g。即自动存储的对象被销毁,它们的内存被释放。

    你初始化为 42 的具有动态存储的整数将被 f 末尾的 q 的析构函数释放。这是因为搬迁建设转移了所有权。

    【讨论】:

      【解决方案2】:

      p 在哪一行被释放?

      p 是一个对象,对象可以销毁。这是可以释放的内存。

      p 最初指向的内存(由new int{42} 分配)在控制离开f 时被释放(当q 被销毁时)。

      p 本身在控制离开g 时被破坏(此时p 为空,即不指向任何东西)。

      【讨论】:

        【解决方案3】:

        为了清楚地改变你的代码 sn-p 如下方式

        #include <iostream>
        #include <memory>
        #include <utility>
        
        struct A
        {
            ~A() { std::cout << "~A()\n"; }
        };
        
        void f(std::unique_ptr<A> q)
        {
            std::cout << "f() begins\n";
        }
        
        void g()
        {
            std::cout << "g() begins\n";
            std::unique_ptr<A> p{new A };
            f( std::move( p ) );
            std::cout << "p == nullptr is " << ( p == nullptr ) << '\n';
            std::cout << "g() endss\n";
        }
        
        int main() 
        {
            std::cout << "Within main()\n";
            g();
        
            return 0;
        }
        

        程序输出是

        Within main()
        g() begins
        f() begins
        ~A()
        p == nullptr is 1
        g() endss
        

        所以函数 g 将指向对象的所有权转移给函数 f。函数 f 结束并确实转移了指向对象的所有权,而不是其他函数。所以在函数 f 退出的那一刻,析构函数被调用了。

        【讨论】:

        • 我不会说gp 的所有权转移到任何地方。 p 仍由 g 作为自动变量“拥有”。转移的是该动态分配对象的所有权。
        • @DanielLangr 当我们说所有权时,当然是指分配对象的分配而不是局部变量。
        【解决方案4】:

        您正在所有权从p 转移到q,因此q 现在拥有该资源。因此,一旦 q 被销毁,即在函数 f 结束时,您的整数就会被销毁。

        唯一指针本身在其作用域的末尾被销毁,即pg() 返回时被销毁,qf() 返回时被销毁。

        另见this small example

        【讨论】:

          【解决方案5】:

          p 将在退出 g 函数时被销毁,就像任何其他具有本地范围的变量一样。只是,当时它不再保存数据;要理解,您实际上不需要单独的函数,只需考虑一下:

          int* n = new int(42);
          
          {
              std::unique_ptr<int> p(n); // p how owns the value pointed to by n
                                         // for brevity, I'll say p owns n from now on,
                                         // although technically not correct...
          
              { // opening another scope! (corresponds to function call)
                  std::unique_ptr<int> q; // another variable, nothing else is a
                                          // function parameter either...
          
                  q = std::move(p);       // this happens, too, when calling a function
                                          // at this point, the ownership is transferred to q
                                          // q now owns n, p is left with just nothing
                                          // (i. e. now holds a null-pointer)
              } // at this point, q is going out of scope; as it is the current
                // owner of n, it will delete it
          
              // p still is in scope, but it has transferred ownership, remember?
          
          } // at this point, p is destroyed; as it doesn't own anything at all any more
            // it dies without doing anything either...
          

          【讨论】:

            猜你喜欢
            • 2020-12-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-08-02
            • 2014-10-09
            • 1970-01-01
            • 2011-01-30
            相关资源
            最近更新 更多