C++: Wie groß ist ein Objekt einer leeren Klasse?

Lesezeit: 6 Minuten

C Wie gros ist ein Objekt einer leeren Klasse
Ashwin Nanjappa

Ich habe mich gefragt, was das sein könnte Größe eines Objekts einer leeren Klasse. Es könnte sicherlich nicht 0 Bytes sein, da es möglich sein sollte, darauf wie auf jedes andere Objekt zu verweisen und zu zeigen. Aber wie groß ist so ein Objekt?

Ich habe dieses kleine Programm verwendet:

#include <iostream>
using namespace std;

class Empty {};

int main()
{
    Empty e;
    cerr << sizeof(e) << endl;
    return 0;
}

Die Ausgabe, die ich sowohl auf Visual C++- als auch auf Cygwin-g++-Compilern erhielt, war 1 Byte! Dies war für mich etwas überraschend, da ich erwartet hatte, dass es die Größe des Maschinenworts (32 Bit oder 4 Byte) haben würde.

Kann jemand erklären warum die Größe von 1 Byte? Warum nicht 4 Bytes? Hängt das auch vom Compiler oder der Maschine ab? Kann jemand auch einen zwingenderen Grund dafür angeben, warum ein leeres Klassenobjekt vorhanden ist wird nicht 0 Bytes groß sein?

  • Ich sehe keinen Grund, warum es nicht Null sein könnte. Aber indem man ihm eine Größe gibt, sind andere Dinge im Compiler einfacher. Wenn Sie ein Array dieser Dinge haben, benötigt jedes Element eine eindeutige Adresse. Eine Größe von 1 macht dies einfach.

    – Martin York

    7. März 2009 um 10:32 Uhr

  • Es kann die Größe Null haben, wenn es ein Unterobjekt der Basisklasse ist.

    – Johannes Schaub – litb

    21. Juli 2012 um 11:24 Uhr

C Wie gros ist ein Objekt einer leeren Klasse
Sol

Zitieren Häufig gestellte Fragen zu Stil und Technik von Bjarne Stroustrup in C++, ist der Grund, warum die Größe ungleich Null ist, “Um sicherzustellen, dass die Adressen von zwei verschiedenen Objekten unterschiedlich sind.” Und die Größe kann 1 sein, weil die Ausrichtung hier keine Rolle spielt, da es nichts zu sehen gibt.

  • Bah, was zum Teufel sollte er über C++ wissen? 🙂

    – paxdiablo

    17. März 2009 um 4:37 Uhr

  • Hat die Notwendigkeit, “sicherzustellen, dass die Adressen von zwei verschiedenen Objekten unterschiedlich sind”, etwas mit C++ zu tun? Ich meine, warum war das Bedürfnis nach C nicht zu spüren?

    – Laser

    16. Mai 2010 um 5:21 Uhr

  • @Lazer, weil es in C keine leeren Strukturen gibt.

    – Aib

    4. November 2010 um 10:16 Uhr

  • @nurabha Der this-Zeiger zeigt zu das Objekt. Es wird nicht im Objekt gespeichert. Wenn es jedoch virtuelle Funktionen gibt, enthält das Objekt einen Zeiger auf die vtable.

    – Tischler

    19. September 2013 um 17:03 Uhr

  • @krish_oza: du denkst falsch. Wenn Sie eine Variable auf dem Stack zuweisen, kann sie keine null Bytes belegen (weil verschiedene Variablen unterschiedliche Adressen benötigen), daher die Mindestgröße 1. Danach liegt es am Compiler. Ähnlich mit new; Wenn der Raum zugewiesen wird, muss eine andere Zuweisung eine andere Adresse haben. Und so weiter. An der leeren Klasse ist nicht unbedingt ein Zeiger beteiligt; Es kann Zeiger auf die Variablen (oder Referenzen oder lokale/Stack-Zuweisungen) geben, aber sie haben keine Nullgröße und nicht unbedingt eine Zeigergröße.

    – Jonathan Leffler

    28. Februar 2014 um 20:35 Uhr

1646973013 136 C Wie gros ist ein Objekt einer leeren Klasse
TrayMan

Der Standard besagt, dass alle am meisten abgeleiteten Objekte sizeof() >= 1 haben:

Sofern es sich nicht um ein Bitfeld (class.bit) handelt, soll ein am meisten abgeleitetes Objekt eine Größe ungleich Null haben und ein oder mehrere Bytes Speicher belegen. Unterobjekte der Basisklasse können eine Größe von Null haben.
ISO/IEC FDIS 14882:1998(E) Einführungsobjekt

  • Ich kann das kaum glauben. Der Standard tut alles, um sicherzustellen, dass Implementierungen freie Hand haben, um gute Arbeit bei der Optimierung zu leisten, indem er die Hände des Implementierers so bindet, dass dies nicht nach dem klingt, was der Standard normalerweise tut (ich könnte mich irren).

    – Martin York

    7. März 2009 um 10:35 Uhr

  • @eSKay – Dies ist erforderlich, damit verschiedene Objekte unterschiedliche Adressen erhalten. Sie könnten beispielsweise keine Karte von Zeigern auf Objekte haben, wenn verschiedene Instanzen dieselbe Adresse hätten.

    – Brian Neal

    16. Mai 2010 um 17:34 Uhr

1646973013 802 C Wie gros ist ein Objekt einer leeren Klasse
paxdiablo

Das ist wirklich ein Implementierungsdetail. Vor langer Zeit dachte ich, es könnten null Bytes oder tausend Bytes sein, das hat keinen Einfluss auf die Sprachspezifikation. Aber nach einem Blick auf den C++17-Standard (expr.sizeof), sizeof ist so definiert, dass immer ein oder mehr zurückgegeben wird, egal was passiert.

Die Größe einer am meisten abgeleiteten Klasse muss größer als Null sein.

Dies ist unter anderem erforderlich, damit Sie mit Arrays von Objekten und Zeigern darauf umgehen können. Wenn Ihre Elemente dann die Größe Null haben dürften &(array[0]) wäre identisch mit &(array[42])was alle Arten von Chaos in Ihren Verarbeitungsschleifen verursachen wird.

Der Grund, warum es möglicherweise kein Maschinenwort ist, besteht darin, dass es keine Elemente enthält, die tatsächlich erfordern, dass es an einer Wortgrenze ausgerichtet ist (z. B. eine ganze Zahl). Zum Beispiel, wenn Sie platzieren char x; int y; Innerhalb der Klasse taktet mein GCC es mit acht Bytes (seit dem zweiten int muss in dieser Implementierung angeglichen werden).


Allerdings scheint dieser spezielle Wortlaut aus C++20 entfernt worden zu sein, was zumindest die Wahrscheinlichkeit von Objekten, die keinen Platz einnehmen können. Der folgende Text wurde jedoch demselben Abschnitt hinzugefügt:

Bei Anwendung auf eine Klasse ist das Ergebnis die Anzahl der Bytes in einem Objekt dieser Klasse einschließlich aller Polsterungen, die zum Platzieren von Objekten dieses Typs in einem Array erforderlich sind.

Da Arrays in der Lage sein müssen, zwischen Elementen zu unterscheiden, würde das bedeuten sizeof müsste mindestens einen zurückgeben, selbst wenn das Objekt selbst technisch gesehen keinen Platz einnehmen würde.

Also unterschiedliche Formulierungen, aber der gleiche Gesamteffekt.

  • Der Grund für “nicht Null” ist, dass unterschiedliche Objekte unterschiedliche Adressen haben sollten. Stellen Sie sich ein Array von Objekten der Größe Null vor. Wie würden Sie es indizieren? In einigen Fällen darf der Compiler dies jedoch wegoptimieren (die leere Basisklassenoptimierung).

    – jalf

    7. März 2009 um 11:07 Uhr

  • @jalf: “Wie würdest du es indizieren?” So wie ich es in C machen würde (zum Beispiel für ein Array von Struct-Objekten)??

    – Laser

    16. Mai 2010 um 5:24 Uhr

  • @eSKay – Sie könnten nicht, wenn sie die Größe 0 hätten. Sie wären alle bei Element 0.

    – Brian Neal

    16. Mai 2010 um 17:35 Uhr

  • @BrianNeal das ist kein Problem, da sie keinen Staat haben, um sich zu differenzieren. Die Probleme treten erst auf, wenn Sie Hinweise berücksichtigen.

    – gha.st

    15. Mai 2013 um 10:16 Uhr

  • Oder nehmen Sie die Größe des Arrays, um seine Länge zu berechnen.

    – gha.st

    15. Mai 2013 um 10:18 Uhr

Obwohl es nicht erforderlich ist, einer leeren Klasse Speicher zuzuweisen, weist der Compiler jedoch den minimal zuweisbaren Speicher zu, der 1 Byte beträgt, um Objekte aus leeren Klassen zu erstellen. Auf diese Weise kann der Compiler zwei Objekte derselben leeren Klasse eindeutig unterscheiden und die Adresse des Objekts einem Zeiger des Typs der leeren Klasse zuweisen.

1646973014 998 C Wie gros ist ein Objekt einer leeren Klasse
Johannes Schaub – litb

Ich denke, es könnte hilfreich sein, auf eine Antwort zu verlinken, die dies auch gut erklärt. Es geht um boost::compressed_pair von Logan Capaldo.

C Wie gros ist ein Objekt einer leeren Klasse
Konstantin Nikitin

Es gibt eine Ausnahme: Arrays der Länge 0

#include <iostream>

class CompletlyEmpty {
  char NO_DATA[0];
};

int main(int argc, const char** argv) {
  std::cout << sizeof(CompletlyEmpty) << '\n';
}

1646973015 290 C Wie gros ist ein Objekt einer leeren Klasse
Peter o.

Das kann dir helfen 🙂
http://bytes.com/topic/c/insights/660463-sizeof-empty-class-structure-1-a

Die Größe einer leeren Klasse oder Struktur ist 1

Der Grund dafür läuft darauf hinaus, den Standard richtig zu implementieren. Eines der Dinge, die der C++-Standard sagt, ist, dass “kein Objekt dieselbe Adresse im Speicher haben darf wie irgendeine andere Variable”. Was ist der einfachste Weg, dies sicherzustellen? Stellen Sie sicher, dass alle Typen eine Größe ungleich Null haben. Um dies zu erreichen, fügt der Compiler Strukturen und Klassen, die keine Datenelemente und keine virtuellen Funktionen haben, ein Dummy-Byte hinzu, damit sie eine Größe von 1 statt einer Größe von 0 haben und dann garantiert eine eindeutige Speicheradresse haben.

989860cookie-checkC++: Wie groß ist ein Objekt einer leeren Klasse?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy