繁体   English   中英

如果类型仅使用 c++11 定义复制构造函数,则使用 std::vector 时 push_back 崩溃

[英]push_back crashed when using std::vector if the type only defined copy constructor with c++11

像这样的代码:

#include <iostream>
#include <vector>

struct Foo
{
    int i;
    double d;
};

class Boo
{
public:
    Boo() : fptr(nullptr) 
    {
        std::cout << "Boo default construct..." << std::endl;
    }
    Boo(int i, double d):fptr(new Foo{i,d})
    {
    }

    Boo(const Boo &rhs) :fptr(new Foo{rhs.fptr->i,rhs.fptr->d})
    {
    }

    Foo *fptr;
};

int main(int argc, char const *argv[])
{
    std::vector<Boo> vec(1);
    Boo b(42, 10.24);
    vec.push_back(b);
    return 0;
}

环境:Ubuntu 16.4 LTS 与 gcc 5.4 g++ -std=c++11 test.cpp -o

。/测试

如果定义移动构造函数,这将工作得很好。 我调试了几个小时,但找不到它有什么问题,可能是因为我不知道 c++ 11 中的一些规则。

有人可以帮我吗? 谢谢!

您的Boo复制构造函数取消引用可能是 null 的指针fptr

std::vector::push_back可以重新分配向量存储。 重新分配可以使用复制构造函数。

这就是您的程序中正在发生的事情。 您正在复制具有 null 指针的Boo

问题在于,在Boo的复制构造函数中,您取消了对nullptr的引用。 这是因为当你写:

std::vector<Boo> vec(1); //this creates a vector of size 1 using Boo's default constrcutor

这是由于上述声明而发生的情况:

  1. 上面的语句使用Boo默认构造函数创建了一个大小为1的名为vec的向量。
  2. 这意味着vec内部已经有1 Boo object 。 此外,由于这个Boo object 是使用默认构造函数创建的,因此它的fptr设置为nullptr

现在,当你写道:

vec.push_back(b);// this adds/push_back object b onto the vector vec so that now its size will be 2

现在,这些是您必须记住的重要事项:

  1. 该向量内部已经有1 Boo object ,其fptrnullptr
  2. 现在您在向量中再添加一个元素,可能会发生重新分配 如果/当这种重新分配发生时,将使用Boo复制构造函数
  3. 当这个复制构造函数用于复制已经存在Boo object 时,它会取消引用它的fptr 但是由于fptrnullptr并且我们知道取消引用nullptr未定义的行为,因此这可能会导致程序出现分段错误,就像您的情况一样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM