หน่วยความจำรั่วในระหว่าง unordered_map :: ใส่ข้อยกเว้น KeyEqual กับ GCC - ทำลายการรับประกันความปลอดภัยข้อยกเว้นที่รัดกุมหรือไม่


10

ฉันใช้ 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( https://stackoverflow.com/a/11699271/1958315 ) หรือไม่ นี่เป็นข้อบกพร่องใน GCC STL หรือไม่


STL จะตรวจจับข้อยกเว้นที่สร้างขึ้นเท่านั้น (หากทำได้) มันจะไม่ป้องกันคุณทำลายมันไม่เปลี่ยนแปลง CPPCON ที่ดีพูดคุยเกี่ยวกับมัน: youtube.com/…
NathanOliver

1
@ NathanOliver-ReinstateMonica อาจต้องทำการอัปเดตเอกสารตามที่อธิบายstd::unordered_map::insertไว้อย่างชัดเจนว่า "1-4) หากมีข้อยกเว้นเกิดขึ้นจากการดำเนินการใด ๆ การแทรกจะไม่มีผล" (เน้นที่เป็นของฉัน) จากที่นี่en.cppreference.com/w/cpp/container/unordered_map/insert
Slava

libc ++ ไม่รั่วไหลหน่วยความจำใด ๆ เมื่อเรียกใช้โปรแกรมนี้
Marshall Clow

@ NathanOliver-ReinstateMonica นั่นไร้สาระ ไลบรารีมาตรฐานมีการจัดการข้อยกเว้นจากชนิดที่ผู้ใช้กำหนด ไม่มีค่าคงที่ที่นี่
โจนาธาน 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]

สำหรับคอนเทนเนอร์ที่เชื่อมโยงหากมีข้อยกเว้นเกิดขึ้นจากการดำเนินการใด ๆ จากภายในฟังก์ชั่นการแทรกหรือ emplace การแทรกองค์ประกอบเดียวการแทรกจะไม่มีผลกระทบ

[unord.req.except]

สำหรับคอนเทนเนอร์ที่ไม่มีการเรียงลำดับหากมีข้อยกเว้นเกิดขึ้นจากการดำเนินการอื่น ๆ นอกเหนือจากฟังก์ชันแฮชของคอนเทนเนอร์จากภายในฟังก์ชันแทรกหรือ emplace แทรกองค์ประกอบเดียวการแทรกจะไม่มีผลกระทบ

เท่าที่ฉันเข้าใจ "ไม่มีผล" หมายถึง "ไม่มีการรั่วไหลของหน่วยความจำ" ภายใต้การตีความเช่นนี้ฉันจะถือว่าการรั่วไหลเป็นข้อบกพร่อง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.