Return 来自函数的取消引用值 shared_ptr
Return a dereferenced value of shared_ptr from a function
这里是一个菜鸟问题。以下代码安全吗?
boost::unordered_set<std::string> func()
{
boost::shared_ptr<boost::unordered_set<std::string>> list =
boost::make_shared<boost::unordered_set<std::string>>();
/* Code to populate the shared_ptr to unordered_set goes here and I do
populate my set. */
return *list;
}
首先会发生什么? Copying/NRVO/moving 或破坏 shared_ptr
导致内存故障?如果不安全,我有什么选择?
您的 shared_ptr 没有做任何事情,您没有 returning 它,您正在 returning 它的内容,即 unordered_set 本身。
您应该将您的函数更改为 return shared_ptr 和 return 它的值。
您可能应该使用 std:: 而不是 boost(除非这是一个旧编译器)。
Copying/NRVO/moving or destruction of shared_ptr there by causing memory fault?
好吧,让我们考虑一下。考虑这个函数:
X foo() {
X x;
return x;
}
这里有两个潜在的顺序,让我们忘记复制省略。
x
被复制到return值,然后x
被销毁。
x
被销毁,然后x
被复制到return值。
(2) 的含义是这样的代码将是未定义的行为,这使得编写函数几乎不可能 - 因为您不能 return 任何局部变量。所以从语言完整性设计的角度来看,最好是 (1).
明确的规则在[stmt.return]:
The copy-initialization of the result of the call is sequenced before the destruction of temporaries at the end of the full-expression established by the operand of the return statement, which, in turn, is sequenced before
the destruction of local variables (6.6) of the block enclosing the return statement.
发生这种情况:
- 制作了指向对象的临时副本。这是函数的 return 值。复制不能省略
- 函数的局部变量,包括共享指针被销毁。
- 当共享指针被销毁时,引用计数递减。如果在函数内没有创建共享指针的副本,refocount 将达到 0,指向的对象将被销毁。
这是安全的,但是使用动态分配和共享指针似乎毫无意义并且如果集合很大,复制的低效率可能会影响性能。
由于您没有证明需要使用指针,我建议使用更简单的替代方法:
boost::unordered_set<std::string> list;
/* Code to populate the unordered_set goes here and I do
populate my set. */
return list;
NRVO 可以应用于此,如果未应用,则 return 值由移动构建。
这里是一个菜鸟问题。以下代码安全吗?
boost::unordered_set<std::string> func()
{
boost::shared_ptr<boost::unordered_set<std::string>> list =
boost::make_shared<boost::unordered_set<std::string>>();
/* Code to populate the shared_ptr to unordered_set goes here and I do
populate my set. */
return *list;
}
首先会发生什么? Copying/NRVO/moving 或破坏 shared_ptr
导致内存故障?如果不安全,我有什么选择?
您的 shared_ptr 没有做任何事情,您没有 returning 它,您正在 returning 它的内容,即 unordered_set 本身。 您应该将您的函数更改为 return shared_ptr 和 return 它的值。
您可能应该使用 std:: 而不是 boost(除非这是一个旧编译器)。
Copying/NRVO/moving or destruction of shared_ptr there by causing memory fault?
好吧,让我们考虑一下。考虑这个函数:
X foo() {
X x;
return x;
}
这里有两个潜在的顺序,让我们忘记复制省略。
x
被复制到return值,然后x
被销毁。x
被销毁,然后x
被复制到return值。
(2) 的含义是这样的代码将是未定义的行为,这使得编写函数几乎不可能 - 因为您不能 return 任何局部变量。所以从语言完整性设计的角度来看,最好是 (1).
明确的规则在[stmt.return]:
The copy-initialization of the result of the call is sequenced before the destruction of temporaries at the end of the full-expression established by the operand of the return statement, which, in turn, is sequenced before the destruction of local variables (6.6) of the block enclosing the return statement.
发生这种情况:
- 制作了指向对象的临时副本。这是函数的 return 值。复制不能省略
- 函数的局部变量,包括共享指针被销毁。
- 当共享指针被销毁时,引用计数递减。如果在函数内没有创建共享指针的副本,refocount 将达到 0,指向的对象将被销毁。
这是安全的,但是使用动态分配和共享指针似乎毫无意义并且如果集合很大,复制的低效率可能会影响性能。
由于您没有证明需要使用指针,我建议使用更简单的替代方法:
boost::unordered_set<std::string> list;
/* Code to populate the unordered_set goes here and I do
populate my set. */
return list;
NRVO 可以应用于此,如果未应用,则 return 值由移动构建。