Speicherlayout von C-Objekten
Frage:
Wie ist C im Speicher angeordnet? Objekt? Ich habe gehört, dass die dynamische Umwandlung nur den Zeiger des Objekts im Speicher anpasst, während die Neuinterpretation es uns ermöglicht, jede Operation an diesem Zeiger durchzuführen. Ich verstehe es nicht ganz. Bitte Angaben machen!
Antwort:
Speicherlayout
Speicherlayout hängt hauptsächlich von der Implementierung ab. Es gibt eine wichtige Ausnahme: Mitgliedsvariablen mit demselben Zugriffsspezifizierer werden in der Deklarationsreihenfolge angeordnet.
§ 9.2.14 非静态数据成员(非联合)具有相同访问控制权的类(Clause 11)被分配,以便后续成员在类对象中具有更高的地址。具有不同访问控制权的非静态数据成员的分配顺序未指定(11)。实现对齐要求可能导致两个相邻成员不会立即相互分配;管理虚拟函数(10.3)和虚拟基类(10.1)的空间要求也可能导致这种情况。
Andere Speicherverwaltung
Zusätzlich zu Mitgliedsvariablen muss eine Klasse oder Struktur auch Mitgliedsvariablen, Unterobjekte der Basisklasse und virtuell verwalten Funktionen (z. B. virtuelle Tabelle) und der für das Auffüllen und Ausrichten dieser Daten bereitgestellte Platz. Es hängt von der Implementierung ab, aber die Itanium ABI-Spezifikation ist eine beliebte Wahl. gcc und clang folgen ihm (zumindest teilweise).
http://mentorembedded.github.io/cxx-abi/abi.html#layout
Itanium ABI
Selbstverständlich ist das Itanium ABI nicht Teil des C-Standards und nicht verbindlich. Ausführlichere Informationen finden Sie in der Dokumentation und den Tools des Implementierers. clang bietet ein Tool zum Anzeigen des Speicherlayouts einer Klasse. Zum Beispiel Folgendes:
class VBase { virtual void corge(); int j; }; class SBase1 { virtual void grault(); int k; }; class SBase2 { virtual void grault(); int k; }; class SBase3 { void grault(); int k; }; class Class : public SBase1, SBase2, SBase3, virtual VBase { public: void bar(); virtual void baz(); // 不允许虚拟成员函数模板,原因考虑内存布局和虚表 // template<typename T> // virtual void quux(); private: int i; char c; public: float f; private: double d; public: short s; }; class Derived : public Class { virtual void qux(); }; int main() { return sizeof(Derived); }
Nachdem Sie eine Quelldatei erstellt haben, die ein Klassenspeicherlayout verwendet, zeigt clang das Speicherlayout an.
$ clang -cc1 -fdump-record-layouts layout.cpp
Layout der Klasse:
*** Dumping AST Record Layout 0 | class Class 0 | class SBase1 (primary base) 0 | (SBase1 vtable pointer) 8 | int k 16 | class SBase2 (base) 16 | (SBase2 vtable pointer) 24 | int k 28 | class SBase3 (base) 28 | int k 32 | int i 36 | char c 40 | float f 48 | double d 56 | short s 64 | class VBase (virtual base) 64 | (VBase vtable pointer) 72 | int j | [sizeof=80, dsize=76, align=8 | nvsize=58, nvalign=8]
Weitere Informationen zum Speicherlayout
Weitere Informationen zu diesem Clang finden Sie unter Die Immobilien finden Sie bei Eli Bendersky Gefunden im Blog:
http://eli.thegreenplace.net/2012/12/17/dumping-a-c-objects-memory-layout-with-clang/
gcc bietet ein ähnliches Tool „-fdump-class-hierarchy“. Für die oben angegebene Klasse gibt sie (unter anderem) Folgendes aus:
Class Class size=80 align=8 base size=58 base align=8 Class (0x0x141f81280) 0 vptridx=0u vptr=((& Class::_ZTV5Class) + 24u) SBase1 (0x0x141f78840) 0 primary-for Class (0x0x141f81280) SBase2 (0x0x141f788a0) 16 vptr=((& Class::_ZTV5Class) + 56u) SBase3 (0x0x141f78900) 28 VBase (0x0x141f78960) 64 virtual vptridx=8u vbaseoffset=-24 vptr=((& Class::_ZTV5Class) + 88u)
Die Mitgliedsvariablen werden nicht aufgelistet (oder zumindest weiß ich nicht, wie ich sie bekomme), aber Sie können es sehen dass sie zwischen Offset 28 und 64 liegen müssen, genau wie im Clang-Layout.
Sie können sehen, dass eine Basisklasse als primär gekennzeichnet ist. Dadurch entfällt die Notwendigkeit dieser Zeigeranpassung, wenn auf die Klasse als SBase1 zugegriffen wird.
Andere Compiler-Anweisungen
Die folgenden äquivalenten Anweisungen gelten für verschiedene Compiler:
Siehe: https://blogs.msdn.microsoft.com/vcblog/2007/05/17/diagnosing-hidden-odr-violations-in-visual-c-and-fixing -lnk2022/
Das obige ist der detaillierte Inhalt vonWie ordnet C Objekte im Speicher an und was bedeutet das für die dynamische Umwandlung und Neuinterpretation?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!