Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Anonymous

unregistriert

1

28.02.2004, 12:54

Allgemeines zur Speicheralloziierung

Hallo :) :) :)

Es folgen einige Überlegungen meinerseits, zu denen ich hoffe Verbessert zu werden, oder Zustimmung zu erhalten:

Die Sprache C++ ist wunderschön, aber welchen Unterschied macht es denn eigentlich praktisch, wenn ich eine Klasse dynamisch erzeuge (mit new), oder statisch?

Es ist wohl sicherer, weil mann den Rückgabewert von new abfragen kann, aber mal Ehrlich: welches Programm reagiert darauf schon korrekt (verhindert den Absturz des Programms)?

gibt Visual C++ eigentlich automatisch ne Fehlermeldung aus, wenn beim statischen alloziieren einer Klasse nicht genügend Speicher da ist?

aber mal generell: Was haltet ihr für sinnvoller, wenn eine Klasse innerhalb eines Gültigkeitsbereiches dauernd gebraucht wird:

Quellcode

1
2
3
4
Gültigkeitsbereich
{
    pClass=new CClass();
}


oder

Quellcode

1
2
3
4
Gültigkeitsbereich
{
    CClass Class;
}


?

Bitte gebt mir meinen Fuß zurück (eng: give me a feedback!)

Samuel G. :) :) :)

Jumping Jack

Treue Seele

Beiträge: 142

Wohnort: Hamburg

Beruf: Schüler

  • Private Nachricht senden

2

28.02.2004, 15:06

der unterschied besteht darin, dass die klasse beim dynamischen alloziieren auf dem heap und ansonsten auf dem stack abgelgt wird. Beide haben ihre vor und nachteile.

Stack
Für jede Funktion wird ein Stackrahmen angelegt, dort werden alle lokalen variablen gespeichert.
Beim verlassen der Funktion werden sie atomatisch gelöscht.

-> keine Speicherlecks
-> die variable existiert nur solange wie sie gebraucht wird
-> alloziierung von speicher geht sehr schnell

-> allerdings ist die größe des Stacks begrenzt (afaik 1MB).
-> Er ist also auch nicht für riesige datenmengen gedacht/geeignet.

Heap

-> Hier können große datenmengen und "langlebige" daten abgelegt werden.

-> für speicherreservierung/freigeabe muss man selber sorgen
-> Speicherlecks können also entstehen
-> Zudem kann der speicher fragmentiert werden (durch viele kleine allokationen)
-> Alloziierung von speicher dauert länger


PS
Das muss jetzt nicht alles stimmen. Falls ihr Fehler findet, bitte posten.

3

28.02.2004, 16:25

Die größe vom Stack wird durch das BS festgelegt. Bei Windows ist es so, das wenn der Stack zu klein ist, automatisch vergrößert wird. Std. größe kenne ich net. Ist aber auch nicht wichtig. Ich denke die anderen BS machen das wie Windows auch.

Zitat

Für jede Funktion wird ein Stackrahmen angelegt, dort werden alle lokalen variablen gespeichert.
Du meintest sicherlich die Klasse. Denn ob die Klasse nun auf dem Stack landet oder auf dem Heap ist für die Methoden einer Klasse irrelewand.

Wenn eine Klasse für das gesamte Projekt verwendet wird, ist es sicherlich besser wenn man sie auf den Stack legt. Dann brauch man sich nicht um das erzeugen und löschen kümmern.

Wenn du allerdings Polymorphie benutzen willst, wird man um eine dynamische Speicherreservierung nicht herum kommen. Das ganze baut schließlich darauf auf. Naja es geht natürlich auch ein bissel anders

Quellcode

1
2
3
4
5
6
7
8
class A { .... };
class B : public A { .... };

int main(void)
{
  B instance;
  A* p = &instance;
}
aber ist wohl etwas umständlicher als wenn man einfach schreiben würde

Quellcode

1
A* p = new B();
oder ;)

Es kommt einfach darauf an was du machen willst. Willst du z.B. ein Array haben von dem nicht von Anfang an feststeht wie groß es ist, benutzt man immer den Heap. Um nicht sagen zu müssen es dürfen nur max n Elemente davon existieren.

Das der Speicher ausgeht ist eher unwarscheinlich bei heutigen Low Cost Rechnern. Wenn der Heap voll ist, wird einfach auf der Festplatte weiter gespeichert. Was natürlich extrem langsam ist. Sollte es denoch vorkommen, meldet sich das BS und nicht die IDE.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Jumping Jack

Treue Seele

Beiträge: 142

Wohnort: Hamburg

Beruf: Schüler

  • Private Nachricht senden

4

28.02.2004, 17:20

hm, ich meine aber dass der Heap (auf 1 MB) begrenzt ist.
(kann natürlich sein, dass das nur im debug modus eines programms ist)
jedenfalls kann man dadurch endlosrekursionen verhinder.

Zitat


Du meintest sicherlich die Klasse.


Womit meine ich die klasse?

Zitat


Denn ob die Klasse nun auf dem Stack landet oder auf dem Heap ist für die Methoden einer Klasse irrelewand.


Ist klar, die instanz der klasse wird ja über den übergebenen this zeiger angesprochen.

5

28.02.2004, 19:49

Zitat von »"DragonMaster"«



Das der Speicher ausgeht ist eher unwarscheinlich bei heutigen Low Cost Rechnern. Wenn der Heap voll ist, wird einfach auf der Festplatte weiter gespeichert. Was natürlich extrem langsam ist. Sollte es denoch vorkommen, meldet sich das BS und nicht die IDE.


einen Stack Overflow kann man aber auch ziemlich einfach verhindern ;)

Quellcode

1
2
3
4
5
6
7
8
9
10
...
...
__try
{
    // irgendwelche Operationen die einen Overflow verursachen könnten...
}
__except(GetExceptionCode() == STATUS_STACK_OVERFLOW)
{
     _resetstkoflw(); // Diese Funktion setzt den Stack nach einem OVerflow wieder zurück. Das ganze liegt in cmallo/malloc.h(ist evtl. Win only; habs nicht probiert)
}



}
Do, ut des!
Ceterum censeo, carthaginem delendam esse

6

29.02.2004, 00:36

Zitat

Womit meine ich die klasse?
Du hattest geschrieben

Zitat

Stack
Für jede Funktion wird ein Stackrahmen angelegt, dort werden alle lokalen variablen gespeichert.
Beim verlassen der Funktion werden sie atomatisch gelöscht.
Da sich der Thread auf Klassen bezieht, denke ich du meintest hier Klassen und nicht Funktionen.

Zitat

hm, ich meine aber dass der Heap (auf 1 MB) begrenzt ist.
(kann natürlich sein, dass das nur im debug modus eines programms ist)
jedenfalls kann man dadurch endlosrekursionen verhinder.
:ohoh: wenn der Heap auf 1MB beschränkt wäre, wären 128MB Riegel wohl überflüssig ;D Wahr wohl ein kleiner gedanken Fehler.

Ich denke es gibt eine max. Grenze für den Stack. Allerdings können für größere Programme 1MB Stack schnell eng werden. Vieleicht finde ich den Text noch einmal über den Stack von Windows. Vieleicht vertu ich mich da jetzt auch.

Zitat

einen Stack Overflow kann man aber auch ziemlich einfach verhindern
Ja klar. Aber Samuel_G fragte ja ob sich das BS meldet oder die IDE. Wenn keine Aufangroutine Implementiert wurde meldet sich eben das BS und nicht die IDE. Es sei denn man ist grad mit dem Debugger am Arbeiten ;)
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Anonymous

unregistriert

7

29.02.2004, 13:29

Klar, aber...

Zitat

einen Stack Overflow kann man aber auch ziemlich einfach verhindern

Code:

...
...
__try
{
// irgendwelche Operationen die einen Overflow verursachen könnten...
}
__except(GetExceptionCode() == STATUS_STACK_OVERFLOW)
{
_resetstkoflw(); // Diese Funktion setzt den Stack nach einem OVerflow wieder zurück. Das ganze liegt in cmallo/malloc.h(ist evtl. Win only; habs nicht probiert)
}




}


Klar, aber man kann ja nie wissen, wo jetzt der Stack Overflow auftreten wird, und man kann ja nicht bei jeder Variable Schreiben den ganzen Block zur Exception-Behandlung schreiben! Deswegen, habe ich drüber nachgedacht, ob es sinnvoll ist speicher immer mit new zu alloziieren, weil ich einfach den Rückgabewert abfragen kann! (zum Beispiel mit nem Template oder Makro) :rolleyes: :rolleyes:

Übrigens: Kann man eigentlich, wenn man einen Speichermanager geschrieben hat, irgendwie Fehlermeldungen erzeugen, die angeben, wo ein Speicher reserviert wurde (Zeile, Zeichen)?
??? ???
Bisher gibt meiner nur Warnungen am Ende aus ("Sie haben einen Speicherblock nicht freigegeben! Schämen Sie sich!"), und gibt den Speicher frei.
:) :)
Harre hoffnungsvoll einer Antwort

Samuel G. :huhu: :huhu:

Jumping Jack

Treue Seele

Beiträge: 142

Wohnort: Hamburg

Beruf: Schüler

  • Private Nachricht senden

8

29.02.2004, 14:31

Zitat


Da sich der Thread auf Klassen bezieht, denke ich du meintest hier Klassen und nicht Funktionen.


Doch ich meinte schon Funktionen. Für klassen wird ja kein Stackrahmen angelegt. Nur für Funktionen/Methoden.

Zitat


wenn der Heap auf 1MB beschränkt wäre, wären 128MB Riegel wohl überflüssig Wahr wohl ein kleiner gedanken Fehler.


Hups, ich meinte natürlich den Stack.
Wenn der Stack nicht begrentzt wäre, würde ja eine endlosrekursion den ganzen Speicher vollhauen, da für jeden neuen aufruf der Funktion ein neuer Stackrahmen mit allen variablen, rücksprungaddresse usw angelegt wird. ich könnte mir allerdings vorstellen dass man die Stackgröße per compilereinstellung ändern kann.

9

29.02.2004, 18:14

Zitat

Klar, aber man kann ja nie wissen, wo jetzt der Stack Overflow auftreten wird, und man kann ja nicht bei jeder Variable Schreiben den ganzen Block zur Exception-Behandlung schreiben!
Die Exception wird ja geworfen (welche Spielt keine Rolle). Wo du diese dann auffängst ist egal. Du kannst eine Komplette Funktion in einen solchen Block spannen, oder auch das gesamte Projekt.

@Memory Manager
Das geht. Schau dir mal den Mamory Manager der GTL an Dort speichere ich die Funktion, die Zeile und die Datei in der Speicher über den Speichermanager Reserviert wurde. In der gtlnew.h ist alles Definiert.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Werbeanzeige