AddressSanitizer GCC 4.8的双重免费错误

时间:2016-10-08 20:03:03

标签: c++ gcc atomic noexcept address-sanitizer

考虑以下玩具计划(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错误。基于类似行的程序必须在多线程应用程序中使用,即使正常编译也会产生Double Free错误。我读了三/五规则,一般在Double Free的情况下被提及,以及其他各种文件,但没有任何效果。

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

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;
   ^

1 个答案:

答案 0 :(得分:4)

std::atomic需要trivially copyable类型,而A不是vector<int>类型,因为UPDATE myTable SET [Column1] = cast([Column1] as varchar(10)) collate SQL_Latin1_General_Cp1251_CS_AS, [Column2] = cast([Column2] as varchar(20)) collate SQL_Latin1_General_Cp1251_CS_AS FROM myTable 类型的成员(例如)不是简单的可复制构造。

GCC only detects a violation of that requirement since version 5.0.

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