C++: Heap/Stack

Gast #4975588
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
Gast #4975604
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.
#4975671
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.
#4984682
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren