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对象。
是这样吗?这是标准所保证的吗?
还有:可能有任何内存泄漏吗?
我希望向量只包含第一个Foo对象。
是这样吗?这是标准所保证的吗?
是的。上面的注释已经解释了emplace_back
甚至从未被调用,因为Foo
构造函数在初始化函数参数时抛出。
但是…
还有:可能有任何内存泄漏吗?
是的,你正在使用我在emplace_back(new X)插入智能指针容器中描述的反模式(也发表在Overload Journal #134 - 2016年8月)。
当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
内部发生异常,该对象将被正确销毁。
相关文章:
- C++代码中的异常安全
- 编写"anti-lack of memory"异常安全代码
- std:string::substr 异常安全吗?
- 如何以异常安全的方式使用放置新?
- 通过引用从 c++ 函数异常返回对象是否安全
- 异常安全服务器
- 实现 std::vector::p ush_back 强异常安全
- 标准::unique_ptr和异常安全
- 如何使用QThreads使无锁生产者-消费者线程交换更加异常安全
- 使功能异常安全
- 与构造函数参数相关的异常安全的习语
- uninitialized_copy() 异常安全吗?
- 为什么我们需要 RAII 来解决异常安全问题
- 异常安全构造函数
- 关于 swap() 操作的异常安全 - 这有什么问题?
- std::vector::擦除异常安全
- 异常安全 - 用于可靠回滚对象状态的模式
- 异常安全的 for 循环
- 异常安全代码和移动语义
- 向量::插入的异常安全保证是什么?