Ich denke, ich verstehe, wie der Stapel funktioniert und was passiert, wenn eine Variable verschoben wird, aber ich kann keine Antwort auf diese Frage finden. Lassen Sie mich erklären:Was passiert mit dem Stapel, wenn eine Variable in einen äußeren Bereich verschoben wird?
Wenn ein neuer Bereich eingegeben/erstellt wird, wird eine bestimmte Menge an Speicher oben auf dem Stapel erworben. Der Stapelzeiger zeigt auf diesen Speicher. Es repräsentiert die aktuelle Größe des Stapels. Wenn der Bereich verlassen wird, wird der Speicher freigegeben, indem der Stapelzeiger an die vorherige Position zurückkehrt.
Verschieben Semantik in C++ 11 oder später verschieben Besitz von einigen Daten von einer Variablen zu einer anderen. Dies vermeidet das Kopieren von Daten, da der Speicher, der die Daten enthält, derselbe bleibt. Nach der Verschiebung zeigt die move-to-Variable auf den Speicherort der Daten im Speicher, und die move-from-Variable wird im Grunde ein Null-Zeiger. Hier könnte ich meinen ersten Fehler machen, indem ich die Bewegungssemantik auf Zeiger zu nahe bringe. Bin ich? Die tatsächliche Frage: Eine Variable wird in einem inneren Bereich erstellt und dann in eine Variable in einem äußeren Bereich verschoben. Dann wird der innere Bereich beendet. Was passiert mit dem Stapel?
Angesichts der oben genannten sollte der Stapelzeiger an seine vorherige Position zurückkehren und den inneren Umfang Speicher freigeben. Dies ist jedoch nicht möglich, da der Speicher des inneren Bereichs immer noch gültig ist, da er jetzt an die äußere Bereichsvariable angehängt ist. Zwischen dem äußeren (möglicherweise globalen) Bereich und dem ehemals inneren Bereichsspeicher kann viel Speicher blockiert/verschwendet sein. Dieser Speicher wird wieder verfügbar, sobald der äußere Bereich beendet wird. Bis dahin ist die Stapelgröße aufgebläht. Ist das wahr? Kann dies vermieden werden? Verhindert der Compiler das?
"Verschiebungssemantik" bedeutet nicht, dass ein Objekt physisch an einen anderen Ort verschoben wird. Es bedeutet nur, dass der von einem Objekt verwaltete Zustand (z. B. ein auf dem Heap zugeordneter Speicherblock, auf dem das Objekt einen Zeiger hält) dem anderen übergeben wird, und zwar auf eine Weise, die durch die Klasse dieses Objekts spezifiziert wird, die oft billiger ist eine vollständige Kopie dieses Staates machen. Dies hat keinen Einfluss darauf, wie der von diesen Objekten belegte Speicher, ob auf dem Stapel oder anderweitig, zugewiesen oder freigegeben wird. –
Genau das ist mein Punkt.Der belegte Speicher bleibt nach dem Verschieben gleich, aber damit der Stapel ordnungsgemäß funktioniert, sollte der gesamte Speicher eines Bereichs freigegeben werden, wenn der Bereich verlassen wird. Vielleicht habe ich es nicht klar erklärt. – bjoern
Die Verschiebungssemantik ist nur für Klassen nützlich, in denen Sie einen Zeiger auf den Heap haben (soweit es Ihnen wichtig ist). Statt einer tiefen Kopie können Sie Ihre Klasse sicher flach kopieren, weil Sie wissen, dass Ihre Besitzrechte an den Heap-Daten allein Ihnen gehören, der vorherige Besitz wurde Ihnen übertragen. So ist die Erinnerung, die dir wichtig ist, wenn sich 'move' bewegt, niemals wirklich im Stapel. Sie kopieren weiterhin Ihre Stack-Objekte (Klassenelemente mit Zeiger auf Heap-Speicher), aber das ist klein und akzeptabel im Vergleich zu einer tiefen Kopie aller Daten im Heap. – Troyseph