次のコードを考えてみてください:std :: move local stack variablesは可能ですか?
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がスコープから外れます。たとえコンパイラがメモリからスタックを取り除いていなくても、スタックから元々存在していた構造が占有していたとしても、少なくとも以前に格納されたリターンアドレスを削除する必要があります。
これは断片化されたスタックにつながり、将来の割り当ては "移動"されたメモリを上書きします。
誰かが私にこのことを説明できますか?
EDIT:すべての まず:あなたの答えをありがとうございました。 しかし、私が学んだこと、私はまだ理解できないから、私はそれが動作することを期待のように動作しません、次の理由:
は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'を返すべきことを除いて、あなたの例は問題ありません。 move構造は 'NewStruct'の* state *を' vecStructs'の新しい要素に移動するだけです。新しい要素は 'NewStruct'とは区別され、どちらの生涯も他の生涯と決してつながっていません。 'push_back'の代わりに[' std :: vector :: emplace_back'](http://en.cppreference.com/w/cpp/container/vector/emplace_back)の使用を検討してください。 –
移動セマンティクスは「スタック上のスロット」を「削除」しません。「指定されていないが使用可能な状態」であるにもかかわらず、(あなたの例では 'NewStruct'から)移動されたオブジェクトが存在することが保証されています。 –
'std :: move'は何も動かず、単なるキャストです:http://stackoverflow.com/questions/21358432/why-is-stdmove-named-stdmove – doctorlove