GCC에서 unorder_map :: insert KeyEqual 예외 중 메모리 누수가 발생합니다.


10

GCC 7.3.1을 사용하고 있지만 버전 9.2.0이라고 생각되는 coliru에서도 테스트되었습니다. 다음을 사용하여 빌드하십시오.

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( https://stackoverflow.com/a/11699271/1958315 ) 의 강력한 예외 안전 보장을 위반합니까 ? GCC STL의 버그입니까?


STL은 생성 된 예외 만 포착합니다 (가능한 경우). 그것은 당신이 변하지 않는 것을 깨뜨리는 것을 막지 않을 것입니다. 그것에 대해 좋은 CPPCON 토론 : youtube.com/...
NathanOliver

1
@ NathanOliver-ReinstateMonica는 아마도 std::unordered_map::insert"1-4) 와 같이 문서를 업데이트해야 할 것입니다. 어떤 작업으로 인해 예외가 발생 하면 삽입은 효과가 없습니다." (emphasis is mine) 여기에서 en.cppreference.com/w/cpp/container/unorder_map/insert
Slava

이 프로그램을 실행할 때 libc ++는 메모리를 누출시키지 않습니다.
Marshall Clow

말도 안되는 @ NathanOliver-ReinstateMonica. 표준 라이브러리는 사용자가 정의한 유형의 예외를 처리해야합니다. 여기에는 깨진 불변이 없습니다.
Jonathan Wakely

@Rai 이것은 버그입니다 gcc.gnu.org/bugs에
Jonathan Wakely

답변:


2

표준에 의해 보증 된 보증 (최신 초안 인용) :

[container.requirements.general]

달리 명시되지 않는 한 ([associative.reqmts.except], [unord.req.except], [deque.modifiers] 및 [vector.modifiers] 참조)이 조항에 정의 된 모든 컨테이너 유형은 다음 추가 요구 사항을 충족합니다.

  • 단일 요소를 삽입하는 동안 insert () 또는 emplace () 함수에서 예외가 발생하면 해당 함수는 영향을 미치지 않습니다.

[associative.reqmts.except]

연관 컨테이너의 경우 단일 요소를 삽입하는 삽입 또는 삽입 기능 내에서 조작으로 예외가 발생하면 삽입이 영향을 미치지 않습니다.

[unord.req.except]

정렬되지 않은 연관 컨테이너의 경우 단일 요소를 삽입하는 삽입 또는 삽입 기능 내에서 컨테이너의 해시 함수 이외의 조작으로 예외가 발생하면 삽입이 적용되지 않습니다.

내가 이해하는 한 "효과 없음"은 "메모리 누수 없음"을 의미합니다. 이러한 해석 하에서 누수는 버그라고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.