1

我有三个问题:

  1. A::str 的内存分配在函数 f 的范围内。将其移动到全局变量 vec 中的元素后,超出 f 范围的内存块是否仍然安全?

  2. 对于 struct B,没有明确给出移动构造函数,是否有像 struct A 这样的默认构造函数?

struct A
{
    A(const char* p):str(p){}
    A(const A&& a) : str(std::move(a.str))
    {
    }

    string str;
};

struct B
{
    B(const char* p):str(p){}

    string str;
};

vector<A>vec;

void f()
{
    vec.emplace_back(A("hello")); //in vc2010 it will invoke emplace_back(T&&)
}

int _tmain(int argc, _TCHAR* argv[])
{
    f();
    const char* p = vec[0].str.c_str();
    cout << p << endl;
    return 0;
}

3.我可以确认这种危险情况在STL容器中从未发生过吗?

struct String
{
    char* pStr; //allocate on heap
    int* someptr; //if point to allocate on stack 
    size_t len;

    String (const String&& s)
    {
    //  something like this:
        pStr = s.pStr;  //ok,safe
        len = s.len; 
        s.pStr = nullptr;

        someptr = s.someptr; //danger
    }
};
4

2 回答 2

1
  1. 这是安全的,因为分配给临时 A 对象的内存被“移动”到向量元素中。

  2. 在 VC++ 2010 中不会自动生成移动构造函数,但 VC++ 2010 是在 C++11 标准完成之前发布的,移动构造函数/赋值运算符的规则有所改变。我不确定 VC++ 2012 是否会生成它们,但无论哪种方式都是安全的(唯一的区别是它可以被复制或移动)。

于 2013-03-14T07:06:29.800 回答
0
  1. 内部分配的任何内存A::str都由它控制,并且不受A创建时有效范围的任何影响。所以你的代码是完全安全的。

  2. 当您既未定义复制构造函数也未定义移动构造函数(也未定义复制/移动赋值运算符)时,编译器将为您生成它们。所以有一个与'B相同的移动默认生成的构造函数。A

于 2013-03-14T07:03:26.327 回答