Forum: Mikrocontroller und Digitale Elektronik C++ RAM STACK HEAP


von fred (Gast)


Lesenswert?

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?

von apr (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.