首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >奇怪的双重免费腐败(GCC 4.9.2,Clang3.6 on Ubuntu Vivid)

奇怪的双重免费腐败(GCC 4.9.2,Clang3.6 on Ubuntu Vivid)
EN

Stack Overflow用户
提问于 2015-10-05 11:33:44
回答 2查看 869关注 0票数 0

以下MWE给出了一个奇怪的地址消毒报告:

代码语言:javascript
复制
#include <vector>

class A {
public:
    A(){}
    ~A(){}
};

class B{
public:

    B(){
        m_grid = new A();
    }
    ~B(){ delete m_grid;}

    A * m_grid = nullptr;

    std::size_t n;
};


int  main(){
    std::vector<B> l;
    l.emplace_back(B{});
}

AsanMangler报告,包括:

代码语言:javascript
复制
=================================================================
==14729==ERROR: AddressSanitizer: attempting double-free on 0x60200000eff0 in thread T0:
    #0 0x7f4207f6e6af in operator delete(void*) (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x586af)
    #1 0x40126f in B::~B() /src/main.cpp:113
    #2 0x401efb in void std::_Destroy<B>(B*) /usr/include/c++/4.9/bits/stl_construct.h:93
    #3 0x401caa in void std::_Destroy_aux<false>::__destroy<B*>(B*, B*) /usr/include/c++/4.9/bits/stl_construct.h:103
    #4 0x4019c8 in void std::_Destroy<B*>(B*, B*) /usr/include/c++/4.9/bits/stl_construct.h:126
    #5 0x401546 in void std::_Destroy<B*, B>(B*, B*, std::allocator<B>&) /usr/include/c++/4.9/bits/stl_construct.h:151
    #6 0x40130f in std::vector<B, std::allocator<B> >::~vector() /usr/include/c++/4.9/bits/stl_vector.h:424
    #7 0x401057 in main /src/main.cpp:170
    #8 0x7f42075d9a3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f)
    #9 0x400ea8 in _start (/src/MAIN+0x400ea8)

0x60200000eff0 is located 0 bytes inside of 1-byte region [0x60200000eff0,0x60200000eff1)
freed by thread T0 here:
    #0 0x7f4207f6e6af in operator delete(void*) (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x586af)
    #1 0x40126f in B::~B() /src/main.cpp:113
    #2 0x401045 in main /src/main.cpp:124
    #3 0x7f42075d9a3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f)

previously allocated by thread T0 here:
    #0 0x7f4207f6e1af in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x581af)
    #1 0x4011ea in B::B() /src/main.cpp:111
    #2 0x401020 in main /src/main.cpp:124
    #3 0x7f42075d9a3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x20a3f)

SUMMARY: AddressSanitizer: double-free ??:0 operator delete(void*)
==14729==ABORTING

编撰:

代码语言:javascript
复制
/usr/bin/g++   -std=c++11 -ftree-vectorize -ftree-vectorizer-verbose=0 -fmessage-length=0 -Wno-enum-compare -g -fsanitize=address -o MAIN main.cpp

有人知道问题出在哪里吗?这里有些东西非常可疑,编译器错误还是奇怪的std库??,到目前为止,我还没有对ubuntu中的c++ 4.9头做任何事情。或者可能是地址消毒剂的假阳性?

我安装了clang-3.6和

它还与行一起崩溃:

代码语言:javascript
复制
clang++   -std=c++14 -fmessage-length=0 -Wno-enum-compare -g -o MAIN main.cpp
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-10-05 11:36:49

没什么奇怪的。指针没有move,指针将被浅表复制,然后您将有双空闲的指针。您可以使用std::unique_ptr,而不是原始指针,或者编写移动构造函数,将nullptr分配给指针。

代码语言:javascript
复制
B(B&& rhs) : m_grid(rhs.m_grid), n(rhs.n)
{
   rhs.m_grid = nullptr;
   rhs.n = 0;
}
票数 3
EN

Stack Overflow用户

发布于 2015-10-05 11:50:42

这不是你使用emplace_back的方式。函数的全部要点是,它避免了movecopy构造,而是执行就地构造,将参数转发给构造函数。实际上,push_back将委托给emplace_back。所以你有一个不必要的移动/复制。

第二,为什么是三人规则?为什么不使用零规则呢?

代码语言:javascript
复制
class B{
public:
    std::vector<A> m_grid;
};

现在,您不需要担心手动资源管理了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32947603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档