7 Stimmen

Wann werden Variablen in C++ aus dem Speicher entfernt?

Ich verwende C++ jetzt schon eine Weile. Ich bin nur nie sicher, wie die Speicherverwaltung funktioniert, also hier geht es:

Ich bin mir zunächst nicht sicher, wie Speicher in einer Funktion freigegeben wird, z. B:

int addTwo(int num)
{
    int temp = 2;
    num += temp;
    return num;
}

Also in diesem Beispiel, würde temp aus dem Speicher entfernt werden, nachdem die Funktion endet? Wenn nicht, wie wird das gemacht. In C# wird eine Variable entfernt, sobald ihr Bereich aufgebraucht ist. Gibt es noch andere Fälle, die ich kennen sollte?

感謝

0 Stimmen

Dieser Code ist reines C. Daher findet hier keine C++-Speicherverwaltung statt. Dies wäre nur der Fall, wenn " new " würde zur Erstellung von temp verwendet werden.

0 Stimmen

Erneut als "C" gekennzeichnet, weil es hier kein C++ gibt, wie jemand anderes unten bemerkt hat.

6 Stimmen

Als C++ gekennzeichnet, da es sich eindeutig um eine C++-Frage handelt und der Fragesteller ausdrücklich nach C++ fragt.

20voto

Thorsten79 Punkte 9872

In C++ gibt es eine sehr einfache Faustregel:

Der gesamte Speicher wird automatisch freigegeben, wenn er nicht mehr benötigt wird, es sei denn, er wurde manuell zugewiesen.

Manuelle Zuweisungen:

  • Jedes durch new() zugewiesene Objekt MUSS durch ein entsprechendes delete() wieder freigegeben werden.
  • Jeder durch malloc() zugewiesene Speicher MUSS durch ein entsprechendes free() wieder freigegeben werden.

Ein sehr nützliches Entwurfsmuster in C++ heißt RAII ( Ressourcenerwerb ist Initialisierung ), die dynamische Zuweisungen an ein skaliertes Objekt bindet, das die Zuweisung in seinem Destruktor freigibt.

Im RAII-Code müssen Sie sich nicht mehr um den Aufruf von delete() oder free() kümmern, da diese automatisch aufgerufen werden, wenn das "Ankerobjekt" den Anwendungsbereich verlässt.

12voto

int3 Punkte 12351

Hier, temp wird auf dem Stack zugewiesen, und der von ihr verwendete Speicher wird automatisch freigegeben, wenn die Funktion beendet wird. Sie können ihn jedoch auch wie folgt auf dem Heap zuweisen:

int *temp = new int(2);

Um sie zu befreien, müssen Sie Folgendes tun

delete temp;

Wenn Sie Ihre Variable auf dem Stack zuweisen, geschieht in der Regel genau das:

Wenn Sie Ihre Funktion aufrufen, erhöht sie den so genannten "Stack Pointer" - eine Zahl, die angibt, welche Adressen im Speicher für die Verwendung durch ihre lokalen Variablen "geschützt" werden sollen. Wenn die Funktion zurückkehrt, wird der Stapelzeiger auf seinen ursprünglichen Wert zurückgesetzt. Mit den Variablen, die Sie in dieser Funktion zugewiesen haben, wird eigentlich nichts gemacht, außer dass der Speicher, in dem sie sich befinden, nicht mehr "geschützt" ist - alles andere kann (und wird) sie überschreiben. Sie sollten also nicht mehr auf sie zugreifen.

Wenn der zugewiesene Speicher auch nach dem Verlassen der Funktion noch vorhanden sein soll, verwenden Sie den Heap.

8voto

Andreas Brinck Punkte 49116

Die lokale Variable temp wird zu Beginn der Funktion auf einen Stapel "geschoben" und bei Beendigung der Funktion vom Stapel "gepoppt".

Hier ist eine Disassemblierung einer nicht optimierten Version:

int addTwo(int num)
{
00411380  push        ebp  
00411381  mov         ebp,esp             //Store current stack pointer
00411383  sub         esp,0CCh            //Reserve space on stack for locals etc
00411389  push        ebx  
0041138A  push        esi  
0041138B  push        edi  
0041138C  lea         edi,[ebp-0CCh] 
00411392  mov         ecx,33h 
00411397  mov         eax,0CCCCCCCCh 
0041139C  rep stos    dword ptr es:[edi] 
    int temp = 2;
0041139E  mov         dword ptr [temp],2 
    num += temp;
004113A5  mov         eax,dword ptr [num] 
004113A8  add         eax,dword ptr [temp] 
004113AB  mov         dword ptr [num],eax 
    return num;
004113AE  mov         eax,dword ptr [num] 
}
004113B1  pop         edi  
004113B2  pop         esi  
004113B3  pop         ebx  
004113B4  mov         esp,ebp                 //Restore stack pointer
004113B6  pop         ebp  
004113B7  ret        

Die Begriffe "geschoben" und "geknallt" sind lediglich als Analogie zu verstehen. Wie Sie der Assembler-Ausgabe entnehmen können, reserviert der Compiler den gesamten Speicher für lokale Variablen usw. in einem Zug, indem er einen geeigneten Wert vom Stapelzeiger abzieht.

6voto

Tom Punkte 41522

Sie wird nicht aus dem Speicher entfernt, sobald die Funktion beendet ist.

Er verbleibt im Speicher, im Stapelrahmen von addTwo, bis ein anderer Prozess (oder derselbe) diesen Teil des Speichers erneut verwendet.

Bis zu diesem Zeitpunkt ist der Zugriff auf temp ein undefiniertes Verhalten.

3voto

Kristopher Johnson Punkte 78933

temp auf dem Stack zugewiesen wird. Wenn die Funktion zurückkehrt, ist sie also weg.

Die Geltungsbereichsregeln in C++ sind ähnlich wie in C#.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X