Forum: PC-Programmierung Größe eines Objektes


von Ampfing (Gast)


Lesenswert?

Hallo zusammen,

ich habe ein MFC-DLL-Projekt hier. Dort gibt es eine Klasse mit 
folgender Definition:
1
class CTsp
2
{
3
   public:
4
      // configuration structure
5
      typedef struct
6
      {
7
         int            iAnzSpur;            // Anzahl der verhandenen Spuren
8
         CSpur*         pSpur[2];            // Spuren
9
         CWidthAdjust*  pWidthAdjust;        // width adjust unit
10
         CTspBoard*     pBoard;              // Transportsteuerung
11
      } ConfTsp;
12
13
      // interface functions
14
      CTsp(const ConfTsp *pConf);
15
      virtual ~CTsp();
16
      
17
      // public members
18
      CLp     m_LpTyp[5]; 
19
      CSpur * m_pSpur[2];
20
21
   private:
22
      // private functions
23
      void GetHole(LPCSTR key, unsigned char p_loecher[], int buffer_len); 
24
25
      // members
26
      const ConfTsp*    m_pConf;
27
      bool              m_bUpdateReady;
28
      bool              m_bSteuerspannung;
29
      bool              m_bInitOk; 
30
      bool              m_bAktualisieren;
31
      int               m_iAnzSpur;
32
};

Jetzt wird ein Objekt dieser Klasse angelegt, anschließend möchte ich 
per sizeof die Größe dieses Objekts ermitteln. Sizeof gibt mir einen 
Wert von 1624 zurück.
Das würde ja bedeuten, dass das Objekt knapp 1,6 kB braucht! Wie kommt 
das denn bitteschön?
Wenn ich das mal grob im Kopf überschlage komme ich auf:
1
      // public members
2
      CLp     m_LpTyp[5];     // 5*4 Bytes = 20 Bytes
3
      CSpur * m_pSpur[2];     // 2*4 Bytes = 8 Bytes
4
      // members
5
      const ConfTsp*    m_pConf;            // 4 Bytes
6
      bool              m_bUpdateReady;     // ?? ich rechne mal mit 4 Bytes
7
      bool              m_bSteuerspannung;  // ?? ich rechne mal mit 4 Bytes
8
      bool              m_bInitOk;          // ?? ich rechne mal mit 4 Bytes
9
      bool              m_bAktualisieren;   // ?? ich rechne mal mit 4 Bytes
10
      int               m_iAnzSpur;         // 4 Bytes
Das macht bei mir in Summe 84 Bytes und nicht 1624! Wo sind bitte die 
1540 Bytes, die das Objekt zusätzlich braucht versteckt? Doch nicht 
etwas in den Member-Funktionen, oder? Da gibt es ein paar (ca. 10 an der 
Zahl), aber die kann er doch nicht bei jedem Objekt anlegen müssen, 
oder? Wenn mich nicht alles täuscht legt er die Funktionen an und 
verweißt dann bei den entsprechenden Objekten per Tabelle drauf, oder? 
Das wären dann nochmal 40 Bytes (bei 10 Funktionen und 4 Bytes pro 
Pointer).

Kann mir jemand erklären, wieso das Objekt dermaßen groß ist?

Ach ja, ich weiß dass es nicht toll ist öffentliche Member-Variablen zu 
haben, die werde ich auch noch beseitigen.

Vielen Dank fürs lesen und viele Grüße

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

>       CLp     m_LpTyp[5];     // 5*4 Bytes = 20 Bytes

Das sind keine Pointer! Daher dürfte die Größe eines solchen Objektes 
deutlich größer sein.

von Karl H. (kbuchegg)


Lesenswert?

Ampfing schrieb:

> 1540 Bytes, die das Objekt zusätzlich braucht versteckt? Doch nicht
> etwas in den Member-Funktionen, oder?

Nein.

> Da gibt es ein paar (ca. 10 an der
> Zahl), aber die kann er doch nicht bei jedem Objekt anlegen müssen,
> oder? Wenn mich nicht alles täuscht legt er die Funktionen an und
> verweißt dann bei den entsprechenden Objekten per Tabelle drauf, oder?

Auch nicht.
Das einzige was zu der sizeof des Objektes beiträgt sind virtuelle 
Funktionen. Und das auch nur in Form eines Pointers, dem sog. V-Table 
Pointer. Ob du also 1 virtuelle Funktion hast oder 20 spielt für ein 
einzelnes Objekt keine Rolle. Es gibt zwar irgendwo im Speicher die 
V-Table für diese Klasse die mit jeder virtuellen Funktion größer wird, 
aber diese V-Table existiert nur einmal für alle Objekte die von dieser 
Klasse erzeugt werden.

Die sizeof wird mehr oder weniger ausschliesslich von 3 (4) Faktoren 
bestimmt:
* Von welche Klassen eine Klasse abgeleitet wurde
* Welche Member eine Klasse hat
* Alignmentanforderungen der Member und damit zusätzliche Padding Bytes
* (Die sizeof kann nicht 0 sein)

von Ampfing (Gast)


Lesenswert?

Hallo,

@Rufus t. Firefly
Oh Mann, da hatte ich nen Stern gesehen, wo keiner ist... Danke! Dann 
werd ich mal versuchen zu finden, warum hier keine Pointer verwendet 
werden...

@Karl heinz Buchegger:
Danke für die Erklärung. Hatte nur noch im Kopf, dass die 
Memberfunktionen über eine Tabelle angesprungen werden. Aber dass das 
nur die virtuellen sind hatte ich nicht gewusst. Macht aber ja auch 
Sinn, da er nur bei denen ja erst zur Laufzeit entscheiden muss, welche 
Funktion er eigentlich wirklich anspringt.

Danke Euch beiden und viele Grüße

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.