Ist diese Art von Speicher auf dem Heap oder dem Stapel erhalten zugeordnet?
-
06-07-2019 - |
Frage
Im Rahmen von C ++ (nicht, dass es wichtig ist):
class Foo{
private:
int x[100];
public:
Foo();
}
Was ich gelernt habe, sagt mir, dass, wenn Sie eine Instanz von Foo erstellen wie folgt:
Foo bar = new Foo();
Dann wird das Array x auf dem Heap reserviert, aber wenn Sie eine Instanz von Foo erstellt wie folgt:
Foo bar;
Dann ist es auf dem Stapel erstellt.
Ich kann nicht finden, Online-Ressourcen, um dies zu bestätigen.
Lösung
eine leichte Modifikation von Ihrem Beispiel Gegeben:
class Foo{
private:
int x[100];
int *y;
public:
Foo()
{
y = new int[100];
}
~Foo()
{
delete[] y;
}
}
Beispiel 1:
Foo *bar = new Foo();
- x und y sind auf dem Heap:
- sizeof (Foo *) auf dem Stapel erstellt.
- sizeof (int) * 100 * 2 + sizeof (int *) ist auf dem Heap
Beispiel 2:
Foo bar;
- x ist auf dem Stapel, und y ist auf dem Heap
- sizeof (int) * 100 ist auf dem Stapel (x) + sizeof (int *)
- sizeof (int) * 100 ist auf dem Heap (y)
Die tatsächlichen Größen leicht aufgrund Klasse / Struktur Ausrichtung können je nach Compiler und Plattform.
Andere Tipps
Genau genommen nach der Norm des Objekt muss nicht auf einem Stapel oder Heap vorhanden ist. Der Standard definiert drei Arten von ‚Lagerdauer‘, aber nicht genau angeben, wie die Speicherung implementiert werden muß:
- statische Speicherdauer
- automatische Speicherdauer
- dynamische Speicherdauer
Automatische Lagerdauer ist in der Regel (fast immer) implementiert, um den Stapel verwendet wird.
Dynamische Speicherdauer typischerweise implementiert, um die Halde mit (letztlich über malloc()
), obwohl dies auch den Benutzer durch die Compiler außer Kraft gesetzt werden kann.
Statische Speicherdauer ist, was es in der Regel als Globals bekannt (oder statischen Speicher).
Der Standard hat dies über diese Dinge zu sagen (die folgenden Auszüge verschiedene Bits von 3,7 bilden - Speicherdauer):
Statische und automatische Speicherdauer sind mit Objekten eingeführt zugeordnet von Erklärungen (3.1) und implizit durch die Umsetzung erstellt (12.2). Die dynamische Speicherdauer ist im Zusammenhang mit erstellten Objekten mit neuer Operator (5.3.4).
...
Alle Objekte, die weder dynamisch haben Lagerdauer noch lokal sind, haben statische Speicherdauer. Der Speicher Für diese Objekte sind für die letzten Laufzeit des Programms (3.6.2, 3.6.3).
...
Lokale Objekte explizit deklariert Auto oder registrieren oder nicht explizit deklariert statische oder extern haben automatische Lagerdauer. Der Speicher für Diese Objekte dauert, bis der Block in die sie gebunden sind Ausfahrten erstellt.
...
Objekte können dynamisch erstellt werden während der Programmausführung (1.9), unter Verwendung von new-Ausdrücke (5.3.4), und zerstört mit Lösch-Ausdrücke (5.3.5). A C + + Implementierung ermöglicht den Zugriff auf und die Verwaltung von dynamischen Speichern über die globalen Zuordnungsfunktionen Betreiber neue und Operator new [] und die globalen Funktionen Deallokation Betreiber löschen und Operator delete [].
...
Die Bibliothek enthält Standard Definitionen für die globale Zuordnung und Freigabe-Funktionen. Etwas globale Zuweisung und Freigabe Funktionen sind austauschbar (18.4.1)
Und schließlich (in Bezug auf das Array in Ihrer Beispiel-Klasse):
3.7.4 Dauer der Unterobjekte [basic.stc.inherit]
Die Lagerdauer des Mitglied Subobjekte, Basisklasse Subobjekte und Array-Elemente ist, dass die kompletten Objekt (1.8).
Ein Objekt des Typs Foo nimmt die Größe von 100 ints in Folge gespeichert. Wenn Sie es auf dem Stapel zu erstellen, werden Sie alles auf dem Stapel bekommen. Wenn Sie es mit neuem tun, wird es auf dem Heap als Teil des Objekts sein.
Dieser Teil der Sprachspezifikation ist, ich bin nicht sicher, was Ihre Frage ist.
Ja, wird das Mitglied Array x
auf dem Heap erstellt werden, wenn Sie das Foo
Objekt auf dem Heap erstellen. Wenn Sie zuteilen dynamischer Speicher für Foo
Sie für Speicher der Länge sizeof(Foo)
fragen (plus eventuell einige Speicher-Overhead, aber lassen wir das vorerst ignorieren), die in Ihrem Beispielcode die Größe von 100 int
s impliziert. Diese hat Fall für die Lebensdauer von Objekten des Typs Foo
(und deren interne Daten) werden Bereiche zu überqueren.
Wenn Sie nicht schaffen das Foo
Objekt auf dem Heap und die interne Anordnung von Foo
ist nicht ein Zeiger auf denen Sie Speicher mit new
in Foo
Konstruktor zuweisen dann die interne Array auf dem Stapel erstellt werden. Auch hier hat das der Fall sein, um für die Anordnung automatisch ohne delete
s gereinigt werden, wenn der Umfang endet. Insbesondere
struct Foo {
int* y;
Foo() : y(new int()) { }
~Foo() { delete y; }
};
wird y
auf dem Heap erstellen, unabhängig davon, ob ein Foo
Objekt auf dem Stack oder auf dem Heap erstellt wurde.
Sie meinen
Foo* bar = new Foo();
Ich nehme an. Das ist in dem Heap erstellt.