C++: Heap/Stack

Gast #4975588
Hallo,

ich spiel gerade etwas mit C++ herum und bin zum Thema dynamische 
Speicherverwaltung gekommen.

Ich habe folgendes Konstrukt:
1
#include <iostream>
2
#include "A.h"
3
#include "B.h"
4
using namespace std;
5

6
int main() {
7

8
  /* Both objects on Stack */
9

10
  A classAStack;
11
  B classBStack;
12

13

14
  /* Both objects on Heap*/
15
//  A *classAHeap = new A();
16
//  B *classBHeap = new B();
17

18
  /* A objects on Heap B ???*/
19
  A *classAHeap = new A();
20

21

22
  return 0;
23
}
1
#ifndef A_H_
2
#define A_H_
3
#include <iostream>
4
#include "B.h"
5

6
class A {
7
public:
8
  A();
9
  virtual ~A();
10

11

12
public:
13
  B b;
14

15
};
16

17
#endif /* A_H_ */
18

19

20
#include "A.h"
21

22

23
A::A() {
24
  std::cout <<"Constructor A called" << std::endl;
25
}
26

27
A::~A() {
28
}

1
#ifndef B_H_
2
#define B_H_
3
#include <iostream>
4

5
class B {
6
public:
7
  B();
8
  virtual ~B();
9
};
10

11
#endif /* B_H_ */
12

13

14
#include "B.h"
15

16
B::B() {
17
  std::cout <<"Constructor B called" << std::endl;
18
}
19
B::~B() {
20
}

Die Ausgabe des Debuggers sieht wie folgt aus:

Temporary breakpoint 6, main () at ../src/HeapStackTest02.cpp:18
18    A classAStack;

Breakpoint 4, B::B (this=0x23aa58) at ../src/B.cpp:12
12    std::cout <<"Constructor B called" << std::endl;

Breakpoint 5, A::A (this=0x23aa50) at ../src/A.cpp:13
13    std::cout <<"Constructor A called" << std::endl;

Breakpoint 4, B::B (this=0x23aa40) at ../src/B.cpp:12
12    std::cout <<"Constructor B called" << std::endl;

Breakpoint 4, B::B (this=0x60004b048) at ../src/B.cpp:12
12    std::cout <<"Constructor B called" << std::endl;

Breakpoint 5, A::A (this=0x60004b040) at ../src/A.cpp:13
13    std::cout <<"Constructor A called" << std::endl;

Breakpoint 1, main () at ../src/HeapStackTest02.cpp:30
30    return 0;


Nun zu meiner Frage:
Wo liegt die Member-Variable b der Klasse A?
Wenn ich mir die Adressen ansehe scheint der Adressbereich 0x23a... der 
Stack zu sein und 0x6000.... der Heap.
Ich arbeite auf einem Windows 64Bit System.
Warum liegt die Member-Variable auch auf dem Heap ohne, dass ein new 
Operator benutz worden ist.

Danke,
Andre
Gast
Ziel von C++ ist -- die Programme sollen genau so performant wie 
Assemblerprogramme sein. Dafür mutet man dem Programmierer einige Knoten 
in den Gedankengängen zu.

Es wird halt schneller, wenn "new A()" nur einmal Speicherbereich für 
alles reservieren muss.

Im laufe der Zeit gewöhnst du dich an diese Sachen.
Andre schrieb:
> Warum liegt die Member-Variable auch auf dem Heap ohne, dass ein new
> Operator benutz worden ist.

Ich nehme an du meinst das letzte B Objekt, denn die anderen B Objekte 
sind ja auf dem Stack. Der Grund ist einfach, dass dein A Objekt auf dem 
Heap liegt und damit liegen alle Membervariablen auch auf dem Heap. Die 
Membervariablen ist ja gerade das was dein Objekt ausmacht.
Für die Anwendung reicht die Vorstellung von sebi_s vollkommen aus. Ein 
Objekt liegt da, wo man es angelegt hat, also auch seine 
Membervariablen.

Ich will hier noch ein bisschen ins Detail gehen, was im Speicher 
passiert.

Ein Objekt besteht aus Membervariablen, die Speicherplatz brauchen. Die 
Größe des Objektes entspricht der Summe der Membervariablen. (Es kommen 
aber auch noch "versteckte" Größen für alignment oder vtable dazu, auf 
die ich hier aber nicht weiter eingehen möchte.)

Will man jetzt ein Objekt anlegen, dann wird dieser Speicherplatz 
entweder auf dem Stack angelegt oder über new/malloc auf dem heap. Das 
Objekt wird dabei über seine Startadresse angesprochen. Die Variablen 
liegen dann jeweils an einem Offset von der Startadresse, der von der 
Struktur des Objektes abhängt.

Beim Zugriff auf dem Objekt ist dann nur noch die Speicheradresse 
relevant, ob diese auf dem Heap oder Stack liegt ist dabei egal, 
Speicher ist Speicher.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.