std::vector<>::emplace_back() 中的异常安全吗?
Exception in std::vector<>::emplace_back() safe?
在std::vector<>::emplace_back()
中抛出异常会发生什么?
例如:
class Foo {
public:
Foo(int bar) {
if (bar == 4) throw std::exception("Something went wrong");
}
}
和
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?
我希望向量只包含第一个 Foo 对象。
是这样吗?这是标准保证的吗?
还有:会不会有内存泄漏?
I would expect the vector to just contain the first Foo object.
Is this the case? And is this guaranteed by the standard?
是的。上面的评论已经解释了 emplace_back
甚至从未被调用,因为 Foo
构造函数在初始化函数的参数时抛出。
但是...
And also: Could there be any memory leaks?
是的,您正在使用我在 Inserting into a container of smart pointers with emplace_back(new X) (also published in Overload Journal #134 - August 2016) 中描述的反模式。
问题发生在 emplace_back
需要重新分配向量并且由于 运行 内存不足而失败时。传递给函数的指针将丢失,因此您泄漏了 Foo
对象。这可能发生在第一次插入时(Foo
构造函数不抛出):
foo_list.emplace_back(new Foo(3));
切勿使用 emplace_back
将原始指针插入 unique_ptr
的容器中,而是使用 make_unique
:
foo_list.emplace_back(std::make_unique<Foo>(3));
或者,如果您必须使用 C++11,则构造 unique_ptr
并插入或放置它,而不是原始指针:
foo_list.emplace_back(std::unique_ptr<Foo>(new Foo(3)));
这样,对象立即由 unique_ptr
拥有,因此如果 emplace_back
内部发生异常,对象将被正确销毁。
在std::vector<>::emplace_back()
中抛出异常会发生什么?
例如:
class Foo {
public:
Foo(int bar) {
if (bar == 4) throw std::exception("Something went wrong");
}
}
和
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?
我希望向量只包含第一个 Foo 对象。
是这样吗?这是标准保证的吗?
还有:会不会有内存泄漏?
I would expect the vector to just contain the first Foo object.
Is this the case? And is this guaranteed by the standard?
是的。上面的评论已经解释了 emplace_back
甚至从未被调用,因为 Foo
构造函数在初始化函数的参数时抛出。
但是...
And also: Could there be any memory leaks?
是的,您正在使用我在 Inserting into a container of smart pointers with emplace_back(new X) (also published in Overload Journal #134 - August 2016) 中描述的反模式。
问题发生在 emplace_back
需要重新分配向量并且由于 运行 内存不足而失败时。传递给函数的指针将丢失,因此您泄漏了 Foo
对象。这可能发生在第一次插入时(Foo
构造函数不抛出):
foo_list.emplace_back(new Foo(3));
切勿使用 emplace_back
将原始指针插入 unique_ptr
的容器中,而是使用 make_unique
:
foo_list.emplace_back(std::make_unique<Foo>(3));
或者,如果您必须使用 C++11,则构造 unique_ptr
并插入或放置它,而不是原始指针:
foo_list.emplace_back(std::unique_ptr<Foo>(new Foo(3)));
这样,对象立即由 unique_ptr
拥有,因此如果 emplace_back
内部发生异常,对象将被正确销毁。