unique_ptr 何时被释放?
When a unique_ptr is deallocated?
在此代码中:
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 移到那里的,但我不确定也不相信这个答案。
您正在转让 所有权从 p
到 q
,因此 q
现在拥有该资源。因此,一旦 q
被销毁,即在函数 f
.
结束时,您的整数就会被销毁
唯一指针本身在其作用域结束时被销毁,即 p
在 g()
时被销毁 returns 并且 q
在 [=18= 时被销毁] returns.
At which line p
is deallocated?
p
是对象,对象可以销毁。可以 释放 .
的内存
p
最初指向的内存(由 new int{42}
分配)在控制权离开 f
时被释放(当 q
被销毁时)。
p
本身在控制离开 g
时被销毁(此时 p
为空,即不指向任何东西)。
At which line p is deallocated?
在声明它的作用域的末尾,即本例中的函数 g。即销毁具有自动存储的对象,并释放其内存。
你初始化为42的动态存储整数将被f末尾q的析构函数释放。这是因为移动构造转移了所有权。
为了清楚起见,请按以下方式更改您的代码片段
#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 退出的那一刻,析构函数被调用。
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...
在此代码中:
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 移到那里的,但我不确定也不相信这个答案。
您正在转让 所有权从 p
到 q
,因此 q
现在拥有该资源。因此,一旦 q
被销毁,即在函数 f
.
唯一指针本身在其作用域结束时被销毁,即 p
在 g()
时被销毁 returns 并且 q
在 [=18= 时被销毁] returns.
At which line
p
is deallocated?
p
是对象,对象可以销毁。可以 释放 .
p
最初指向的内存(由 new int{42}
分配)在控制权离开 f
时被释放(当 q
被销毁时)。
p
本身在控制离开 g
时被销毁(此时 p
为空,即不指向任何东西)。
At which line p is deallocated?
在声明它的作用域的末尾,即本例中的函数 g。即销毁具有自动存储的对象,并释放其内存。
你初始化为42的动态存储整数将被f末尾q的析构函数释放。这是因为移动构造转移了所有权。
为了清楚起见,请按以下方式更改您的代码片段
#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 退出的那一刻,析构函数被调用。
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...