Rò rỉ bộ nhớ trong unordered_map :: chèn ngoại lệ KeyEqual với GCC - phá vỡ bảo đảm an toàn ngoại lệ mạnh?


10

Tôi đang sử dụng GCC 7.3.1, nhưng cũng đã thử nghiệm trên coliru, mà tôi tin là phiên bản 9.2.0. Xây dựng với những điều sau đây:

g++ -fsanitize=address -fno-omit-frame-pointer rai.cpp

Đây là 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";
    }
}

Chạy nó cho kết quả:

> ./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).

Tôi không thấy bất kỳ rò rỉ bộ nhớ nào với Visual C ++ ( Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28314 for x64).

Điều này có phá vỡ sự đảm bảo an toàn ngoại lệ mạnh mẽ của unordered_map::insert( https://stackoverflow.com/a/11699271/1958315 ) không? Đây có phải là một lỗi trong GCC STL không?


STL sẽ chỉ bắt ngoại lệ mà nó tạo ra (nếu có thể). Nó sẽ không bảo vệ bạn phá vỡ nó bất biến. CPPCON hay nói về nó: youtube.com/ Từ
NathanOliver

1
@ NathanOliver-ReinstateMonica có lẽ tài liệu cần phải được cập nhật sau đó, như std::unordered_map::insertđã nói rõ "1-4) Nếu một ngoại lệ được ném bởi bất kỳ thao tác nào , việc chèn không có hiệu lực." (nhấn mạnh là của tôi) từ đây en.cppreference.com/w/cpp/container/unordered_map/insert
Slava

libc ++ không rò rỉ bất kỳ bộ nhớ khi chạy chương trình này.
Marshall Clow

@ NathanOliver-RebstateMonica thật vớ vẩn. Thư viện chuẩn phải xử lý các trường hợp ngoại lệ từ các loại người dùng xác định. Không có bất biến bị phá vỡ ở đây.
Jonathan Wakely

@Rai đây là một lỗi, vui lòng báo cáo gcc.gnu.org/bugs
Jonathan Wakely

Câu trả lời:


2

Bảo đảm bắt buộc theo tiêu chuẩn (trích dẫn từ dự thảo mới nhất):

[container.requirements.general]

Trừ khi có quy định khác (xem [Associative.reqmts.except], [unord.req.except], [deque.modifier] và [vector.modifier]) tất cả các loại container được xác định trong Điều khoản này đều đáp ứng các yêu cầu bổ sung sau:

  • nếu một ngoại lệ được ném bởi hàm insert () hoặc emplace () trong khi chèn một phần tử duy nhất, hàm đó không có hiệu ứng.

[kết hợp.reqmts.except]

Đối với các thùng chứa kết hợp, nếu một ngoại lệ được ném bởi bất kỳ thao tác nào từ bên trong hàm chèn hoặc hàm chèn một phần tử, thì phần chèn không có hiệu lực.

[unord.req.except]

Đối với các thùng chứa kết hợp không có thứ tự, nếu một ngoại lệ được ném bởi bất kỳ thao tác nào ngoài hàm băm của hàm chứa trong một hàm chèn hoặc hàm em chèn một phần tử, thì phần chèn không có tác dụng.

Theo tôi hiểu, "không có tác dụng" ngụ ý "không rò rỉ bộ nhớ". Theo cách giải thích như vậy, tôi sẽ coi rò rỉ là một lỗi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.