简体   繁体   English

std :: vector <> :: emplace_back()中的异常安全吗?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM