Reputation: 850
I have three questions:
A::str's memory allocated in the scope of function f. After moving it to the element in global var vec, is the block of memory still safe when out the scope of f?
For struct B, not giving a move constructor explicitly, is there a default one like 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.And can I confirm this dangerous situation never happen in STL container?
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
}
};
Upvotes: 1
Views: 135
Reputation: 6668
It's safe, because the memory allocated for the temporary A object is "moved" into the vector element.
In VC++ 2010 no move constructor is automatically generated, but VC++ 2010 was released before the C++11 standard was finished and the rules for move constructors/assignment operators changed somewhat. I'm not sure whether VC++ 2012 generates them, but either way it's safe (the only difference is that it may be copied or moved).
Upvotes: 1
Reputation: 171117
Any memory allocated internally by A::str
is controlled by it and not affected in any way by what scope was in effect when the A
was created. So your code is perfectly safe.
When you define neither a copy constructor nor a move constructor (nor a copy/move assignment operator), the compiler will generate them for you. So B
has a move default-generated constructor identical to A
's one.
Upvotes: 0