GCC unordered_map::insert KeyEqual 异常期间的内存泄漏 - 打破了强大的异常安全保证?
Memory leak during unordered_map::insert KeyEqual exception with GCC - breaking the strong exception safety guarantee?
我使用的是 GCC 7.3.1,但也在 coliru 上进行了测试,我认为它是 9.2.0 版。使用以下内容构建:
g++ -fsanitize=address -fno-omit-frame-pointer rai.cpp
这里是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";
}
}
运行 结果是:
> ./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).
我没有看到 Visual C++ 有任何内存泄漏 (Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28314 for x64
)。
这会破坏 unordered_map::insert
() 的强异常安全保证吗?这是 GCC STL 中的错误吗?
标准规定的保证(引用最新草案):
[container.requirements.general]
Unless otherwise specified (see [associative.reqmts.except], [unord.req.except], [deque.modifiers], and [vector.modifiers]) all container types defined in this Clause meet the following additional requirements:
- if an exception is thrown by an insert() or emplace() function while inserting a single element, that function has no effects.
[associative.reqmts.except]
For associative containers, if an exception is thrown by any operation from within an insert or emplace function inserting a single element, the insertion has no effect.
[unord.req.except]
For unordered associative containers, if an exception is thrown by any operation other than the container's hash function from within an
insert or emplace function inserting a single element, the insertion
has no effect.
据我了解,“没有效果”意味着“没有内存泄漏”。在这样的解释下,我会认为泄漏是一个错误。
我使用的是 GCC 7.3.1,但也在 coliru 上进行了测试,我认为它是 9.2.0 版。使用以下内容构建:
g++ -fsanitize=address -fno-omit-frame-pointer rai.cpp
这里是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";
}
}
运行 结果是:
> ./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).
我没有看到 Visual C++ 有任何内存泄漏 (Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28314 for x64
)。
这会破坏 unordered_map::insert
() 的强异常安全保证吗?这是 GCC STL 中的错误吗?
标准规定的保证(引用最新草案):
[container.requirements.general]
Unless otherwise specified (see [associative.reqmts.except], [unord.req.except], [deque.modifiers], and [vector.modifiers]) all container types defined in this Clause meet the following additional requirements:
- if an exception is thrown by an insert() or emplace() function while inserting a single element, that function has no effects.
[associative.reqmts.except]
For associative containers, if an exception is thrown by any operation from within an insert or emplace function inserting a single element, the insertion has no effect.
[unord.req.except]
For unordered associative containers, if an exception is thrown by any operation other than the container's hash function from within an insert or emplace function inserting a single element, the insertion has no effect.
据我了解,“没有效果”意味着“没有内存泄漏”。在这样的解释下,我会认为泄漏是一个错误。