2015-03-08 15 views
5

Zum Beispiel gibt es eine StrukturWarum Padding hinzugefügt werden, wenn Char nach Int kommt?

struct A 
{ 
char a; 
int i; 
}; 

In diesem Fall haben wir ein [1 Byte] + padding [3 Byte] + int [4 Byte] = 8.

Lassen Sie uns jetzt etwas machen Aktualisierung in über Struktur,

struct A 
{ 
int i; 
char a; 
}; 

in diesem Fall char nach int kommt und keine Notwendigkeit, Paddingbytes hinzuzufügen, bedeutet dies, sizeof (A) = 5 Byte, aber in diesem Fall auch die 8-Byte-Ergebnis, das ich bekommen. Warum ?

Ok, und was ist mit diesem Fall

struct s 
    { 
     int b; 
     double c; 
     char a; 
    }; 

Logik weiter unten Nach besteht ein: size = b[4 bytes] + padding[4 bytes] + c[8] + a[1] + padding[7 bytes to align with double] = 24, aber nach der Ausführung I 16 erhalten, wie dies möglich?

Antwort

6

In diesem Fall char kommt nach int und keine Notwendigkeit Paddingbytes hinzufügen, bedeutet das sizeof(A) = 5 Byte, aber in diesem Fall ich auch das 8 Byte Ergebnis. Warum ?

Zuerst müssen Sie verstehen, warum Padding benötigt wird?
Wiki sagt, dass:

Speicherausrichtung ist die Art und Weise Daten in einem Computerspeicher angeordnet und aufgerufen. Es besteht aus zwei separaten, aber verwandten Problemen: Datenausrichtung und Datenstruktur Padding. Wenn ein moderner Computer von einer Speicheradresse liest oder in eine Speicheradresse schreibt, wird dies in wortgroßen Blöcken (z. B. 4-Byte-Blöcken in einem 32-Bit-System) oder größer erfolgen. Datenausrichtung bedeutet, dass die Daten in einem Speicher versetzt werden, der einem Vielfachen der Wortgröße entspricht, was die Systemleistung aufgrund der Art und Weise, wie die CPU Speicher behandelt, erhöht. Um die Daten auszurichten, kann es notwendig sein, einige bedeutungslose Bytes zwischen dem Ende der letzten Datenstruktur und dem Beginn des nächsten, das Datenstrukturauffüllen ist, einzufügen.

Um die Größe von mehreren 4 (Ausrichtung von int) zu machen, wird der zweite Schnipsel mit 3 Bytes aufgefüllt. Nach der Kompilierung wird die zweite Schnipsel für die richtige Ausrichtung aufgefüllt werden als

struct A 
{ 
    int i; 
    char a; 
    char Padding[3]; // 3 bytes to make total size of the structure 8 bytes 
};  

EDIT: Denken Sie immer daran, die beiden goldenen Regeln des Bauwerks padding:

  • Padding nur eingesetzt wird, wenn ein Strukturelement ist gefolgt von ein Mitglied mit einer größeren Ausrichtung Anforderung oder an der Ende o f die Struktur.
  • Das letzte Element wird mit der Anzahl der erforderlichen Byte aufgefüllt, sodass die Gesamtgröße der Struktur ein Vielfaches der größten Ausrichtung eines Strukturelements sein sollte.

Bei

struct s 
{ 
    int b; 
    double c; 
    char a; 
}; 

Ausrichtung statt wie

struct s 
{ 
    int b;    // 4 bytes. b is followed by a member with larger alignment. 
    char Padding1[4]; // 4 bytes of padding is needed 
    double c;   // 8 bytes 
    char d;   // 1 byte. Last member of struct. 
    char Padding2[7]; // 7 bytes to make total size of the structure 24 bytes 
}; 

Beachten Sie auch, dass durch die Reihenfolge der Elemente in einer Struktur zu verändern, ist es möglich, die Menge der Polsterung zu ändern erforderlich, um die Ausrichtung beizubehalten. Dies kann durchgeführt werden, indem Mitglieder nach absteigenden Ausrichtungsanforderungen sortiert werden.

struct s 
{ 
    double c; // 8 bytes 
    int b;  // 4 bytes 
    char a;  // 1 byte. Only last member will be padded to give structure of size 16 
}; 
+0

Aber ist es richtig, , dass Doppel kann mit Offset beginnen, der ein Vielfaches von 8 ist? In Ihrer Erklärung ist der Offset von double gleich 5. –

+0

@ user2846015; Wie groß ist die Größe von 'struct s { double c; int b; Zeichen a; }; '? – haccks

+0

in dieser Reihenfolge wird es c [8] + b [4] + a [1] + Padding [3, um mit Doppel auszurichten] = 16 –

0

Nicht nur jedes Mitglied der struct hat Daten ausgerichtet werden, aber die struct selbst hat auf die Größe des größten Elements in den struct zu ausgerichtet ist. So wird Padding zu struct A so hinzugefügt, dass seine Größe ein Vielfaches des größeren von sizeof i und sizeof a sein sollte.

Hier finden Sie aktuelle C FAQ here

0

Wenn man ein Array von Strukturen haben wird, werden alle Elemente innerhalb des Arrays müssen die gleiche Größe und Ausrichtung aufweisen; Dies würde bedeuten, dass die Größe für Objekte in einem Array ein Vielfaches der Ausrichtung sein muss. Die einzige Zeit, in der es sinnvoll wäre, eine Struktur zu haben, deren Größe kein Vielfaches der Ausrichtung wäre, wäre, wenn sie nicht direkt in ein anderes Array integriert wäre, sondern stattdessen als Teil einer anderen Struktur verwendet wurde. Diese Art von Situation tritt manchmal auf, aber nicht oft genug, um besondere Aufmerksamkeit im Sprachdesign zu verdienen.

1

Der Grund, warum der Compiler Padding am Ende Ihrer Struktur hinzufügen muss, ist, dass die Struktur Teil eines Arrays sein kann und jedes Element eines Arrays ordnungsgemäß ausgerichtet sein muss.

Es scheint, dass Ihre Plattform möchte, dass ein Int auf 4 Bytes ausgerichtet wird.

Wenn Sie ein Array Ihrer struct A erklären:

struct A array[2]; 

Dann wird der erste int Mitglied array[1] sollte auch eine Ausrichtung von 4 Bytes haben. Der Compiler puffert also Ihre struct A auf 8 Bytes, um das zu erreichen, während, wenn er kein Padding hinzufügt und sizeof(struct A) 5 Bytes wären, wäre array[1] nicht richtig ausgerichtet.

(Beachten Sie, dass ein Compiler nicht Polsterung dazwischen Array-Elemente einfügen, Polster haben einen Teil der Array-Elemente selbst seit sizeof array sein müssen das gleiche wie sizeof(struct A) * 2 im obigen Fall sein)