Wie der Heap-Werke in C ++

Das Haufen

ist ein amorphes Speicherblock, der Ihre C ++ Programm nach Bedarf zugreifen können. Erfahren Sie, warum es sie gibt und wie es zu benutzen.

Genau so ist es möglich, einen Zeiger auf eine Funktion zu übergeben, ist es möglich, eine Funktion einen Zeiger zurück. Eine Funktion, die die Adresse einer zurückgibt doppelt wie folgt erklärt wird:

double * fn (void) -

Allerdings müssen Sie sehr vorsichtig sein, wenn ein Zeiger zurück. Um die Gefahren zu verstehen, muss man etwas über den Geltungsbereich von Variablen kennen.

Begrenzte Umfang in C ++

Szurechtkommen über dem der Bereich eine Variable definiert ist. Betrachten Sie den folgenden Code-Schnipsel:

// Die folgende Variable zugänglich alle Funktionen auf // und solange die // Programm ausgeführt wird (global scope) int intGlobal definiert - // die folgende Variable intChild zugänglich // nur auf die Funktion und definiert ist nur // solange C ++ ist die Ausführung Kind () oder eine // Funktion, die Kind () aufruft (Funktionsumfang) void Kind (void) {int intChild -} // die folgende Variable intParent hat Funktion // scopevoid Eltern (void) {int intParent = 0-child () - int intLater = 0-intParent = intLater-} int main (int nArgs, char * pargs []) {parent () -}

Dieses Programm Fragment beginnt mit der Deklaration einer Variablen intGlobal. Diese Variable besteht aus der Zeit der Ausführung des Programms beginnt, bis es beendet wird. Du sagst das intGlobal # 147-hat Programmumfang. # 148- Sie sagen auch, dass die Variable # 147-geht in Rahmen # 148- schon vor der Funktion Main() wird genannt.

Die Funktion Main() sofort ruft Elternteil(). Das erste, was der Prozessor sieht in Elternteil() ist die Erklärung von intParent. An diesem Punkt, intParent geht in Umfang - das heißt, intParent für den Rest der Funktion festgelegt und verfügbar Elternteil().

Die zweite Aussage in Elternteil() ist der Aufruf Kind(). Wiederum ist die Funktion Kind() deklariert eine lokale Variable, diesmal intChild. Der Umfang der Variablen intChild wird auf die Funktion begrenzt Kind(). Technisch, intParent nicht innerhalb des Umfangs der definierten Kind() weil Kind() hat keinen Zugang zu intParent- jedoch die Variable intParent wird fortgesetzt, während zu existieren Kind() ausgeführt wird.

Wann Kind() Ausgänge, die Variable intChild den Gültigkeitsbereich verlässt. Nicht nur ist intChild nicht mehr zugänglich ist, existiert nicht mehr. (Der Speicher belegt durch intChild ist mit dem allgemeinen Pool zurückgegeben für andere Dinge verwendet werden.)

Wie Elternteil() weiterhin ausgeführt wird, wird die Variable intLater geht in den Rahmen an der Erklärung. An dem Punkt, dass Elternteil() kehrt zu Main(), beide intParent und intLater gehen aus dem Rahmen.

weil intGlobal global in diesem Beispiel erklärt wird, ist es für alle drei Funktionen verfügbar und bleibt für die Lebensdauer des Programms zur Verfügung.

Untersuchen des Umfangs Problem in C ++

Das folgende Codesegment kompiliert ohne Fehler funktioniert aber nicht (nicht Sie nur, dass Hass?):

double * Kind (void) {double dLocalVariable-Rückkehr dLocalVariable-} void parent (void) {double * pdLocal-pdLocal = child () - * pdLocal = 1,0-}

Das Problem mit dieser Funktion ist, dass dLocalVariable nur im Rahmen der Funktion definiert ist, Kind(). Somit wird durch die Zeit, die Speicheradresse dLocalVariable wird zurückgegeben, Kind(), es bezieht sich auf eine Variable, die nicht mehr existiert. Der Speicher, dLocalVariable ehemals besetzten wahrscheinlich für etwas anderes verwendet wird.

Dieser Fehler ist sehr verbreitet, weil es in einer Reihe von Möglichkeiten kriechen kann. Leider wird dieser Fehler nicht dazu führen, das Programm sofort zu stoppen. In der Tat kann das Programm funktionieren die meiste Zeit - das heißt, wird das Programm fortgesetzt, so lange zu arbeiten, wie die Erinnerung früher besetzt durch dLocalVariable wird nicht sofort wiederverwendet werden. Solche intermittierende Probleme sind die am schwierigsten zu lösen.

Die Bereitstellung einer Lösung, die die Halde in C ++

Der Umfang Problem entstand, weil C ++ die lokal definierten Speicher nahm zurück, bevor der Programmierer bereit war. Was benötigt wird, ist ein Speicherblock vom Programmierer gesteuert. Sie kann den Speicher zuweisen, und legen Sie sie zurück, wenn sie will - nicht, weil C ++ denkt, es ist eine gute Idee. Ein solcher Speicherblock genannt Haufen.

Heap-Speicher wird unter Verwendung zugewiesen die neu Schlüsselwort durch die Art des Objekts gefolgt zuzuteilen. Das neu Befehl bricht ein Teil des Speichers aus dem Heap groß genug, um die angegebene Art von Objekt zu halten und gibt seine Adresse. Zum Beispiel weist die folgenden ein doppelt Variable aus dem Heap:

double * Kind (void) {double * pdLocalVariable = new double-Rückkehr pdLocalVariable-}

Diese Funktion funktioniert nun korrekt. Obwohl die Variable pdLocalVariable den Gültigkeitsbereich verlässt, wenn die Funktion Kind() kehrt die Erinnerung an die pdLocalVariable bezieht sich nicht. Ein Speicherplatz zurück durch neu nicht außerhalb des Bereichs, bis sie explizit auf den Haufen mit dem Schlüsselwort zurückgegeben löschen, welche speziell für diesen Zweck ausgelegt:

Leere Elternteil (void) {// Kind () gibt die Adresse eines Blocks // Heap memorydouble * pdMyDouble = child () - // Wert speichern dort * pdMyDouble = 1,1 - // ... // jetzt kehrt die Speicher in den heapdelete pdMyDouble-pdMyDouble = 0 - // ...}

Hier haben Sie den Zeiger wieder durch Kind() wird verwendet, um einen doppelten Wert zu speichern. Nachdem die Funktion der Speicherstelle beendet ist, wird es auf die Halde zurückgeführt. Die Funktion Elternteil() setzt den Zeiger auf 0, nachdem der Heap-Speicher zurückgegeben wurde - dies nicht erforderlich ist, aber es ist eine sehr gute Idee.

Wenn der Programmierer versucht versehentlich etwas zu speichern, in * pdMyDouble nach dem löschen, das Programm wird sofort mit einer aussagekräftigen Fehlermeldung abstürzen.

Sie können verwenden neu Arrays aus dem Haufen zu verteilen, wie gut, aber man muss ein Array mit der Rückkehr löschen[] Stichwort:

int * nArray = new int [10] -nArray [0] = 0-delete [] nArray-

Technisch new int [10] ruft die neu[] Operator, aber es funktioniert genauso wie neu.

Menü