【发布时间】:2014-03-21 19:48:51
【问题描述】:
我发现 (thanks to a StackOverflow comment) 我的代码中有一个安全漏洞:
std::vector<std::unique_ptr<Item>> items;
template<class... TS> Item& create(TS&&... mArgs)
{
auto item(new Item(std::forward<TS>(mArgs)...);
items.emplace_back(item); // Possible exception and memory leak
return *item;
}
基本上,如果emplace_back 抛出,则使用原始new 分配Item 可能会泄漏内存。
解决方案从不使用原始new,而是在方法主体中使用std::unique_ptr。
std::vector<std::unique_ptr<Item>> items;
template<class... TS> Item& create(TS&&... mArgs)
{
auto item(std::make_unique<Item>(std::forward<TS>(mArgs)...);
items.emplace_back(std::move(item));
return *item; // `item` was moved, this is invalid!
}
如您所见,返回 item 无效,因为我必须使用 std::move 移动 item 以将其放置到 items 容器中。
我想不出需要将item 的地址存储在附加变量中的解决方案。然而,原始(有缺陷的)解决方案非常简洁易读。
有没有更优雅的方式来返回被移动以放置在容器中的std::unique_ptr?
【问题讨论】:
-
return *items.back(); -
你为什么首先返回对
unique_ptr内部的引用? -
如果
items向量突然消失了怎么办? -
顺便说一句,请注意代码只提供基本的异常保证:如果
emplace_back抛出,参数将已经被移出。 -
@avakar,有没有办法解决这个问题?
标签: c++ c++11 return unique-ptr emplace