Hallo,
um mein Wissen etwas zu festigen, mal wieder eine Frage an die Profis.
Worin liegt der Unterschied zwischen folgenden Ansätzen.
Im Main.cpp File:
----------------------------------------------------------
KlasseA *oKlasseA = new Klasse();
void main(void)
{
}
-----------------------------------------------------------
Dieses Objekt "oKlasseA" wird, soweit ich weiß, zur Laufzeit des
Programms im HEAP Speicher angelegt.
Bedeutet, es muss mit delete gelöscht werden, ansonsten wird "sein" HEAP
Speicher nicht freigegeben.
Da ich denke, dass folgendes nicht sauber ist, will ich betonen, dass es
mir nur ums Verständnis von HEAP geht.
Angenommen ich erstelle obiges Objekt in einer Funktion C welche von
Funktion B aufgerufen wird. Funktion C gibt einen Zeiger auf das Objekt
im Heap an Funktion B zurück. Das Objekt wurde auf dem Heap erzeugt aber
wird nie gelöscht.
Funktion B könnte doch nun auf dieses Objekt im Heap über den Zeiger
zugreifen? Die Funktion in der es erzeugt wurde ist nicht mehr da, aber
das auf dem Heap erzeugte Objekt wurde ja nicht gelöscht.
Dann noch eine Frage zu folgendem:
Im Main.cpp File:
----------------------------------------------------------
int a = 2; //Variante A
void main(void)
{
int b = 3; //Variante B
for(;;)
{
}
}
-----------------------------------------------------------
Wo wird die Variable a und wo Variable b angelegt?
Wird Variable b auf dem Stack und Variable a im RAM angelegt?
Mir ist klar, dass letztens alles auf dem RAM liegt.... Stack ist ein
Stapelspeicher.
Sollte man Variante A oder Variante B nutzen oder macht das keinen
Unterschied?
HEAP wird zur Laufzeit belegt und diese Objekte sollten gelöscht werden,
wenn sie nicht mehr benötigt werden.
STACK wird bei Variablen in Funktionen benötigt .... Also, wenn eine
Funktion eine andere aufruft, dann werden die Variablen in der
aufrufenden Funktion wohl in den Stapelspeicher gegeben und beim
Rücksprung wieder herausgeholt?
Und alles andere was Modulglobal angelegt ist, landet fest im Ram?
Könnt ihr das so bestätigen?
C++ kennt vier Möglichkeiten der "storage duration": automatic, static, dynamic und thread. Es gibt kein "RAM", kein "Stack" und auch keinen "Heap" – Das alles sind Implementierungsdetails. Variante A definiert eine Variable des Typs int mit "static storage duration". Sie wird zu beginn des Programms allokiert und zu Ende des Programms zerstört. Weitere Varianten:
1 | int foo() { |
2 | static auto x = 0; |
3 | …
|
4 | }
|
5 | |
6 | struct Bar { |
7 | static int y; |
8 | };
|
9 | …
|
10 | int Bar::y |
11 | |
12 | extern int z; |
Variante B definiert eine Variable mit "auto storage duration". Sie wird mit Ende des umschließenden Blocks zerstört. http://en.cppreference.com/w/cpp/language/storage_duration
1 | …
|
2 | KlasseA *oKlasseA = new Klasse(); |
3 | ^^^^^^^^^^^^ // Hier |
4 | …
|
Das erzeugt eine Variable mit "dynamic storage duration". Objekte werden bei Bedarf durch die "dynamic memory allocation functions" (veraltet: new, besser std::make_unique, std::make_shared) angefordert. Zerstört werden diese Objekte auch nur auf Anforderung (delete, bzw. massiv besser über die smart pointer). Also zur ersten Frage: Ja wenn man ein Objekt mit new anlegt und den Pointer darauf zurück gibt, existiert das Objekt auch nach dem Ende der Funktion noch. (Bis man eben per delete den Speicher wieder frei gibt). Aber: Das sollte man ganz dringend vermeiden und stattdessen, wenn man denn dringend dynamic storage duration benötigt, stattdessen etwas in der Form schreiben:
1 | std::unique_ptr<KlasseA> void foo() { |
2 | auto ret = std::make_unique<KlasseA>(); |
3 | …
|
4 | return ret; |
5 | }
|
Auf diese Art werden Speicherleaks vermieden und die Signatur definiert klar wer verantwortlich für die Ressource ist. Faustregel: Einfach die beiden operatoren "new" und "delete" aus dem eigenen Code verbannen. Wenn man dynamic storage braucht werden Objekte mit "make_unique" erzeugt. Jeder "raw pointer" ist immer "non owning", also eine Sicht auf ein Objekt und nicht für die Zerstörung des Objekts verantwortlich. Die zweite Frage steht oben. Variante A hat static storage duration, Variante B auto storage duration. Was ist nun besser? Das kommt darauf an… Generell gesprochen ist auto storage duration das Mittel der Wahl, bis man denn etwas anderes benötigt.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.