Forum: PC-Programmierung C++: Heap/Stack


von Andre (Gast)


Lesenswert?

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

von Noch einer (Gast)


Lesenswert?

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.

von Sebastian V. (sebi_s)


Lesenswert?

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.

von M.K. B. (mkbit)


Lesenswert?

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.

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.