[英]Exception in std::vector<>::emplace_back() safe?
What happens when an exception is thrown in std::vector<>::emplace_back()
? 在
std::vector<>::emplace_back()
引发异常时会发生什么?
For example: 例如:
class Foo {
public:
Foo(int bar) {
if (bar == 4) throw std::exception("Something went wrong");
}
}
and 和
std::vector<std::unique_ptr<Foo>> foo_list;
foo_list.emplace_back(new Foo(3));
try {
foo_list.emplace_back(new Foo(4));
} catch (std::exception error) {
// How bad is it?
}
// Whats inside foo_list now?
I would expect the vector to just contain the first Foo object. 我希望向量仅包含第一个Foo对象。
Is this the case? 是这样吗 And is this guaranteed by the standard?
这是标准所保证的吗?
And also: Could there be any memory leaks? 而且:会不会有内存泄漏?
I would expect the vector to just contain the first Foo object.
我希望向量仅包含第一个Foo对象。
Is this the case?
是这样吗 And is this guaranteed by the standard?
这是标准所保证的吗?
Yes. 是。 The comments above already explained that
emplace_back
never even gets called because the Foo
constructor throws while initializing the arguments for the function. 上面的注释已经说明了
emplace_back
甚至都不会被调用,因为Foo
构造函数在初始化函数的参数时会抛出该异常。
But ... 但是...
And also: Could there be any memory leaks?
而且:会不会有内存泄漏?
Yes, you are using the anti-pattern that I have described at Inserting into a container of smart pointers with emplace_back(new X) (also published in Overload Journal #134 - August 2016 ). 是的,您使用的是我在使用emplace_back(new X)插入智能指针容器中描述的反模式(也已在Overload Journal# 134- 2016年8月发布 )中描述。
The problem happens when emplace_back
needs to reallocate the vector and that fails due to running out of memory. 当
emplace_back
需要重新分配向量并且由于内存不足而失败时, emplace_back
发生问题。 The pointer passed into the function will be lost, and so you leak the Foo
object. 传递给函数的指针将丢失,因此您泄漏了
Foo
对象。 This can happen for the first insertion (where the Foo
constructor doesn't throw): 第一次插入可能会发生这种情况(
Foo
构造函数不会抛出该Foo
):
foo_list.emplace_back(new Foo(3));
Never use emplace_back
to insert raw pointers into a container of unique_ptr
, instead use make_unique
: 切勿使用
emplace_back
将原始指针插入unique_ptr
容器中,而应使用make_unique
:
foo_list.emplace_back(std::make_unique<Foo>(3));
Or if you have to use C++11 then construct the unique_ptr
and insert or emplace that, not a raw pointer: 或者,如果您必须使用C ++ 11,则构造
unique_ptr
并将其插入或放置,而不是原始指针:
foo_list.emplace_back(std::unique_ptr<Foo>(new Foo(3)));
This way the object is owned by a unique_ptr
immediately, and so if an exception happens inside emplace_back
the object will be destroyed correctly. 这样,该对象将立即由
unique_ptr
拥有,因此,如果emplace_back
内部发生异常, emplace_back
该对象将被正确销毁。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.