AddressSanitizer GCC 4.8的双重免费错误

Double Free error with AddressSanitizer GCC 4.8

本文关键字:免费 错误 GCC AddressSanitizer      更新时间:2023-10-16

考虑以下玩具程序(prog.cpp):

class A {
public:
    vector<int> vec;
    A() noexcept {}
    A(vector<int> s) : vec(s) {}
};
class B {
private:
    vector<atomic<A>> a_table;
public:
    B(int capacity) : a_table(capacity) {}
    void update(int index) {
        A newValue(vector<int>(10,1));
        a_table[index].store(newValue);
    }
};

int main(int argc, char** argv) 
{
B b(5);
b.update(2);
return 0;
}

当正常编译时(g++ prog.cpp -latomic),工作良好。但是当编译为g++ -fsanitize=address -fno-omit-frame-pointer prog.cpp -latomic时,执行时会产生双重自由错误。基于上述类似代码行的程序必须在多线程应用程序中使用,在这种情况下,即使是正常的编译也会产生Double Free错误。我读了"三/五规则",这是在双重自由的情况下通常提到的,还有各种其他文件,但都不起作用。

另外,从class A的默认构造函数中删除noexcept指定符会产生这个奇怪的错误,这也是我想知道的。

error: function ‘std::atomic<_Tp>::atomic() [with _Tp = A]’ defaulted on its first declaration with an exception-specification that differs from the implicit declaration ‘std::atomic<A>::atomic()’
   atomic() noexcept = default;
   ^

std::atomic需要一个平凡的可复制类型,而你的A不是,因为它的vector<int>类型的成员(例如)不是平凡的可复制构造的。

从5.0版本开始,GCC只检测违反该要求。

旧版本的gcc编译代码并不意味着它是有效的