Das Auffüllen wird durchgeführt, um bestimmte Datentypen auszurichten, d. H. Sicherzustellen, dass Daten eines bestimmten Typs eine Adresse haben, die ein Vielfaches einer bestimmten Zahl ist. Dies variiert zwischen verschiedenen CPU-Modellen, aber oft werden 2-Byte-Ganzzahlen auf Adressen ausgerichtet, die Vielfache von 2 und 4-Byte-Ganzzahlen zu Adressen sind, die Vielfache von 4 sind. Zeichen müssen normalerweise nicht ausgerichtet werden.
Wenn also nur ein Feld in einer Struktur vorhanden ist, dann ist, solange die Struktur an einer Adresse mit der richtigen Grenze platziert ist, keine Auffüllung erforderlich. Und es wird immer so sein: Das System richtet Blöcke immer an der größten Grenze aus, die jemals benötigt wird, normalerweise 4 Bytes oder 8 Bytes. Die eine Sache in der Struktur wird an einer richtigen Grenze sein. Das Problem tritt nur auf, wenn Sie mehrere Felder haben, da dann die Länge eines Felds nicht dazu führt, dass das nächste Feld an der richtigen Grenze ist. In Ihrem Beispiel haben Sie also ein char, das natürlich 1 Byte benötigt, und ein int, das 4 annimmt. Nehmen wir an, die Struktur befindet sich an der Adresse 0x1000. Ohne Character würde das Zeichen dann auf 0x1000 und das Int auf 0x1001 gesetzt. Int-Werte sind jedoch effizienter, wenn sie an 4-Byte-Grenzen liegen. Daher fügt der Compiler einige Pad-Bytes hinzu, um ihn zur nächsten solchen Grenze, 0x1004, zu verschieben. So, jetzt haben Sie char (1 Byte), Padding (3 Bytes), int (4 Bytes), insgesamt 8 Bytes.
Es gibt nichts, was Sie tun können, um die Situation in diesem Fall zu verbessern. Jede Struktur wird auf eine 4- oder 8-Byte-Grenze ausgerichtet, wenn also das Minimum 5 Bytes beträgt, wird dies in der Praxis immer auf mindestens 8 aufgerundet. (Der sizeof zeigt den Abstand zwischen Structs nur innerhalb, aber der Speicher ist immer noch verloren.)
In anderen Fällen können Sie die Anzahl der zusätzlichen Pad Bytes minimieren, indem Sie die Reihenfolge der Felder neu anordnen. Wie gesagt, du hattest drei Chars und drei Int's. Wenn Sie die Struktur als
struct {char a; int b; char c; int d; char e; int f;}
dann der Compiler erklären wird 3 Byte nach dem ersten Zeichen fügen Sie die erste int auszurichten, und dann drei weitere Bytes nach dem zweiten Zeichen des zweiten int auszurichten. Das ergibt char (1) + pad (3) + int (4) + char (1) + pad (3) + int (4) + char (1) + pad (3) + int (4) = 24.
Aber wenn Sie stattdessen es erklärt:
struct {char a; char c; char e; int b; int d; int f;}
dann würden Sie char (1) + char (1) + char (1) + Pad (1) + int (4) + int (4 erhalten) + int (4) = 16.
Vor Jahren habe ich den Rat gelesen, immer zuerst die größten Elemente zu setzen, um die Polsterung zu minimieren, dh erst Longs, dann Ints, dann Shorts und dann Chars.
Wenn Sie Tausende oder Millionen davon zuweisen, können Sie mit dieser Technik viel Speicher sparen. Wenn Sie nur ein oder zwei zuweisen, wird es nicht viel ausmachen.
I <3 ASCII ART! –
Hi, Dann wie wäre es mit der case struct {int b; Zeichen a; } X; Hier, wenn wir int betrachten, um von der Speicherstelle in mehreren von 4 und Char zu Stat später zu starten. Die Polsterung erfolgt auch in diesem Fall. Warum ist hier ein Padding erforderlich, wenn alle Datenmember den Randbedingungen folgen? – Laavaa
@AbhishekSrinath wegen Arrays. Wenn Sie 'X x [2]' haben, muss das zweite Element - 'x [1]' - auf 4 Bytes ausgerichtet werden, da sein erstes Mitglied ein 'int' ist, das auf 4 Bytes ausgerichtet werden muss. –