44 Stimmen

Wie wird die Größe einer Struktur mit Bitfeldern bestimmt/gemessen?

#include <stdio.h>

typedef struct size
{
        unsigned int a:1;
        unsigned int b:31;
        unsigned int c:1;
} mystruct;

int main()
{
        mystruct a;
        printf("%d", sizeof(a));
        return 0;
}
  • Mit int b:31 ist die Ausgabe 8.
  • Mit int b:1 ist der Ausgang 4.
  • Mit int b:32 ist der Ausgang 12.

Kann mir jemand den Grund dafür erklären?

63voto

MdT Punkte 831

Es kommt auf die Reihenfolge an. Der folgende Code ergibt die Ausgabe: 8

#include<stdio.h>

typedef struct size
{
        unsigned int b:32;
        unsigned int a:1;
        unsigned int c:1;
}mystruct;

int main(int argc, char const *argv[])
{
        mystruct a;
        printf("\n %lu \n",sizeof(a));
        return 0;
}

Unsigned int ist eine 32-Bit-Ganzzahl, die 4 Bytes belegt. Der Speicher wird fortlaufend im Speicher zugewiesen.


Option 1:

unsigned int a:1;       // First 4 bytes are allocated
unsigned int b:31;      // Will get accomodated in the First 4 bytes
unsigned int c:1;       // Second 4 bytes are allocated

Ausgabe: 8


Option 2:

unsigned int a:1;       // First 4 bytes are allocated
unsigned int b:32;      // Will NOT get accomodated in the First 4 bytes, Second 4 bytes are allocated
unsigned int c:1;       // Will NOT get accomodated in the Second 4 bytes, Third 4 bytes are allocated

Ausgang: 12


Option 3:

unsigned int a:1;       // First 4 bytes are allocated
unsigned int b:1;       // Will get accomodated in the First 4 bytes
unsigned int c:1;       // Will get accomodated in the First 4 bytes

Leistung: 4


Option 4:

unsigned int b:32;      // First 4 bytes are allocated
unsigned int a:1;       // Second 4 bytes are allocated
unsigned int c:1;       // Will get accomodated in the Second 4 bytes

Leistung: 8

31voto

Steve Jessop Punkte 264569

Sie sagen nicht, ob Sie wissen, was Bitfelder sind, aber ich nehme an, Sie wissen es.

Offensichtlich bei Ihrer Umsetzung unsigned int ist eine 32-Bit-Ganzzahl, die 4 Bytes belegt. Dies erklärt das erste und zweite Beispiel. Es ist klar, dass 3 Bitfelder mit insgesamt 33 Bit nicht in ein einziges Byte passen. unsigned int Daher werden im ersten Beispiel 8 Bytes benötigt. 3 Bitfelder mit insgesamt 3 Bits passen sicherlich in ein unsigned int daher nur 4 Bytes im zweiten Beispiel.

Außerdem kann ein Bitfeld nicht mehrere ganze Zahlen umfassen. Dies erklärt das dritte Beispiel. Ich kann mich nicht erinnern, ob das eine Anforderung des Standards oder nur ein Detail Ihrer Implementierung ist. So oder so, da b 32 Bits beträgt, füllt es einen ganzen unsigned int allein und zwingt beide von a y c ihre eigenen Räume zu besetzen unsigned int , vor und nach dem mittleren. Also 12 Bytes.

13voto

yuan Punkte 2364

Según Antwort von Steve Jessop um seine Antwort zu ergänzen, indem ich einige Dokumente hinzufüge, die hilfreich sein könnten.

Ein Member einer Struktur oder Union kann einen beliebigen vollständigen Objekttyp mit Ausnahme eines variabel modifizierten Typs haben; außerdem kann ein Member so deklariert werden, dass er aus einer bestimmten Anzahl von Bits besteht (einschließlich eines Vorzeichenbits, falls vorhanden). Ein solches Element wird als Bit-Feld seiner Breite ein Doppelpunkt vorangestellt ist

Eine Implementierung kann jede adressierbare Speichereinheit zuweisen, die groß genug ist, um ein Bit-Feld aufzunehmen. Wenn genügend Platz vorhanden ist, wird ein Bitfeld, das in einer Struktur unmittelbar auf ein anderes Bitfeld folgt, in benachbarte Bits der gleichen Einheit gepackt. Reicht der Platz nicht aus, ist es von der Implementierung abhängig, ob ein Bitfeld, das nicht passt, in die nächste Einheit gepackt wird oder ob es benachbarte Einheiten überlappt. Die Reihenfolge der Zuweisung von Bitfeldern innerhalb einer Einheit (höherwertig zu niederwertig oder niederwertig zu höherwertig) ist implementierungsabhängig. Die Ausrichtung der adressierbaren Speichereinheit ist nicht spezifiziert.

Innerhalb eines Strukturobjekts haben die Mitglieder, die keine Bitfelder sind, und die Einheiten, in denen sich Bitfelder befinden, Adressen, die in der Reihenfolge, in der sie deklariert werden, aufsteigen . Ein Zeiger auf ein Strukturobjekt, der entsprechend umgewandelt wurde, zeigt auf sein Anfangsglied (oder, wenn dieses Glied ein Bit-Feld ist, auf die Einheit, in der es sich befindet) und umgekehrt. Innerhalb eines Strukturobjekts kann es unbenannte Auffüllungen geben, aber nicht an seinem Anfang.

--ISO/IEC 9899:201x 6.7.2.1

10voto

DigitalRoss Punkte 138823

Ausrichtung

Der Compiler rundet die Größe der Struktur auf 32 Bit, die Größe jedes Objekts, das er möglicherweise referenziert, auf 32 Bit und behält gleichzeitig die Reihenfolge der Bitfelder bei.

Wenn Sie also ein 32-Bit-Element in der Mitte und 1-Bit-Elemente auf jeder Seite haben, müssen Sie 3 32-Bit-Wörter zuweisen: 12 Bytes.

In den beiden anderen Fällen geht es nur darum, in wie wenige 32-Bit-Objekte die Bitfeldsequenz gepackt werden kann, wobei die Feldreihenfolge erhalten bleibt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X