Rai*_*Rai 10 c++ gcc stl unordered-map exception-safety
我正在使用 GCC 7.3.1,但也在coliru 上进行了测试,我认为它是 9.2.0 版。使用以下内容构建:
g++ -fsanitize=address -fno-omit-frame-pointer rai.cpp
Run Code Online (Sandbox Code Playgroud)
这是rai.cpp:
#include <iostream>
#include <unordered_map>
int main()
{
try
{
struct MyComp {
bool operator()(const std::string&, const std::string&) const {
throw std::runtime_error("Nonono");
}
};
std::unordered_map<std::string, std::string, std::hash<std::string>, MyComp> mymap;
mymap.insert(std::make_pair("Hello", "There"));
mymap.insert(std::make_pair("Hello", "There")); // Hash match forces compare
} catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
运行它的结果是:
> ./a.out
Caught exception: Nonono
=================================================================
==72432==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 32 byte(s) in 1 object(s) allocated from:
...
Direct leak of 4 byte(s) in 1 object(s) allocated from:
...
Indirect leak of 60 byte(s) in 2 object(s) allocated from:
...
SUMMARY: AddressSanitizer: 96 byte(s) leaked in 4 allocation(s).
Run Code Online (Sandbox Code Playgroud)
我没有看到 Visual C++ ( Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28314 for x64)有任何内存泄漏。
这是否打破了unordered_map::insert(/sf/answers/818949001/)的强大异常安全保证?这是 GCC STL 中的错误吗?
标准规定的保证(引用自最新草案):
[容器.要求.一般]
除非另有说明(请参阅 [associative.reqmts. except]、[unord.req. except]、[deque.modifiers] 和 [vector.modifiers]),本条款中定义的所有容器类型均满足以下附加要求:
- 如果在插入单个元素时 insert() 或 emplace() 函数抛出异常,则该函数不会产生任何影响。
[关联.reqmts.例外]
对于关联容器,如果插入单个元素的 insert 或 emplace 函数中的任何操作引发异常,则插入无效。
[unord.req. except]
对于无序关联容器,如果在插入单个元素的 insert 或 emplace 函数中除容器的哈希函数之外的任何操作引发异常,则插入无效。
据我了解,“没有影响”意味着“没有内存泄漏”。根据这样的解释,我认为泄漏是一个错误。