struct MyStruct
{
int iInteger;
string strString;
};
void MyFunc(vector<MyStruct>& vecStructs)
{
MyStruct NewStruct = { 8, "Hello" };
vecStructs.push_back(std::move(NewStruct));
}
int main()
{
vector<MyStruct> vecStructs;
MyFunc(vecStructs);
}
为什么这个工作?
在调用`MyFunc`的时候,返回地址应该被放置在当前线程的堆栈上。现在创建了`NewStruct`对象,它也应该被放置在堆栈上。通过使用`std::move`,我告诉编译器,我不打算再使用`NewStruct`的引用了。它可以窃取内存。(`push_back`函数是具有移动语义的函数。)
但是当函数返回并且`NewStruct`超出范围时,即使编译器不会从堆栈中删除原来存在的结构所占用的内存,它至少要删除之前存储的返回地址。
这将导致堆栈碎片化,未来的分配将覆盖“移动”的内存。
请有人给我解释一下这个问题吗?
编辑:
首先,非常感谢您的回答。
但是根据我所了解的,我仍然无法理解为什么以下内容不像我期望的那样工作:
struct MyStruct
{
int iInteger;
string strString;
string strString2;
};
void MyFunc(vector<MyStruct>& vecStructs)
{
MyStruct oNewStruct = { 8, "Hello", "Definetly more than 16 characters" };
vecStructs.push_back(std::move(oNewStruct));
// At this point, oNewStruct.String2 should be "", because its memory was stolen.
// But only when I explicitly create a move-constructor in the form which was
// stated by Yakk, it is really that case.
}
void main()
{
vector<MyStruct> vecStructs;
MyFunc(vecStructs);
}
main
函数需要返回int
之外,你的例子很好。移动构造函数只是将NewStruct
的状态移动到vecStructs
中的新元素中。新元素与NewStruct
是不同的,它们的生命周期没有任何联系。考虑使用std::vector::emplace_back
代替push_back
。 - François AndrieuxNewStruct
)保证存在,尽管处于“未指定但可用状态”。 - el.pescado - нет войнеstd::move
不会移动任何东西,它只是一个类型转换:https://dev59.com/emEi5IYBdhLWcg3wWLPc - doctorlove