C++ 无序映射期间内存泄漏::使用GCC插入KeyEqual异常-破坏强异常安全保证?

C++ 无序映射期间内存泄漏::使用GCC插入KeyEqual异常-破坏强异常安全保证?,c++,gcc,stl,unordered-map,exception-safety,C++,Gcc,Stl,Unordered Map,Exception Safety,我使用的是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 ope

我使用的是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";
    }
}
<>我没有看到任何内存泄漏,VisualC++(<代码>微软(R)C/C++ +优化编译器版本19.24.8314,用于X64 < /C> >)
这是否打破了
无序映射::insert
()的强大异常安全保证?这是GCC STL中的一个缺陷吗?

该标准规定的担保(引用最新草案):

[集装箱.要求.概述]

除非另有规定(见[关联需求除外]、[无序需求除外]、[需求修饰符]和[向量修饰符]),本条款中定义的所有容器类型均满足以下附加要求:

  • 如果插入单个元素时insert()或emplace()函数引发异常,则该函数不会产生任何效果
[关联需求除外]

对于关联容器,如果插入单个元素的insert或emplace函数中的任何操作引发异常,则插入无效

[未通知要求除外]

对于无序关联容器,如果容器的哈希函数以外的任何操作从 插入或放置函数插入单个元素,即插入 没有效果


据我所知,“没有效果”意味着“没有内存泄漏”。在这样的解释下,我会认为漏洞是一个错误。

STL只会抓住它产生的例外(如果可以)。它不会防止你破坏它的不变性。很好的CPPCON谈论它:@NathanOliver可能需要更新文档,因为
std::unordered_map::insert
清楚地说“1-4)如果任何操作引发异常,则插入无效。”(重点是我的)从这里开始,运行这个程序时,libc++不会泄漏任何内存。@NathanOliver,这是胡说八道。标准库必须处理来自用户定义的类型的异常。这里没有损坏的不变量。@Rai这是一个错误,请报告它
> ./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).