Ich verstehe nicht, warumGröße einer Struktur mit zwei Void-Zeigern ist 4?
struct e{
void * a;
void * b[];
}
sizeof (e) == 4, während
struct f{
void * a;
void * b;
}
hat sizeof (f) == 8.
Ich verstehe nicht, warumGröße einer Struktur mit zwei Void-Zeigern ist 4?
struct e{
void * a;
void * b[];
}
sizeof (e) == 4, während
struct f{
void * a;
void * b;
}
hat sizeof (f) == 8.
Die zweite in der ersten Struktur ist kein Zeiger, sondern ein FAM - flexibles Array-Mitglied. Es wird verwendet, wenn Sie einen langen Puffer haben und einen e
am Anfang dieses Puffers platzieren. Sie können dann den verbleibenden Speicher, der dem Objekt e
folgt, mit diesem FAM indizieren und diesen Speicher als Array von void*
behandeln.
Die Norm sagt (Betonung von mir)
Als Sonderfall, das letzte Element einer Struktur mit mehr als einem benannten Mitglied kann hat einen unvollständigen Typen Array; Dies wird als flexibles Array-Element bezeichnet. In den meisten Fällen wird das flexible Array-Element ignoriert. Insbesondere ist die Größe der Struktur so, als ob das flexible Array-Element weggelassen würde, mit der Ausnahme, dass es möglicherweise mehr abschließende Auffüllung als die Auslassung implizieren würde.
Zum Beispiel können die folgenden Code-Ausgänge 1
für die Struktur ohne, aber 4
für die Struktur mit dem FAM auf GCC, weil für den Zugriff ganzen Zahlen die FAM Notwendigkeit richtig ausgerichtet werden (auf einer 4-Byte-Grenze in diesem Dieses Beispiel)
struct A {
char a;
};
struct B {
char a;
int flex[];
};
int main() {
printf("sizeof A: %d\nsizeof B: %d\n",
(int)sizeof(struct A),
(int)sizeof(struct B)
);
struct B *b = malloc(sizeof *b + sizeof(int[3]));
b->a = 'X';
b->flex[0] = 1;
b->flex[1] = 2;
b->flex[2] = 3;
free(b);
}
Da Sie die Inhalte in verschiedenen Beiträgen zusammengestellt und ein Beispiel hinzugefügt haben, habe ich Ihre Antwort gegenüber der vorherigen akzeptiert. –
struct e{
void * a;
void * b[];
// ^^
}
Die []
hat in Eine Struktur macht b
ein C99 "flexibles Array-Mitglied". Damit die Größe des a
sizeof(e)
nur zählen, die 4.
Von C99 ist § 6.7.2.1/16:
Als Sonderfall, das letzte Element einer Struktur mit mehr als einem benannten Mitglied kann einen unvollständigen Array-Typ haben; Dies wird flexibles Array-Element genannt. In den meisten Situationen wird das flexible Array-Element ignoriert. Insbesondere ist die Größe der Struktur so, als ob das flexible Array-Element weggelassen würde, mit der Ausnahme, dass es möglicherweise mehr abschließende Auffüllung hat, als die Auslassung implizieren würde.
Wenn jedoch ein
.
(oder->
) -Operator über einen linken Operanden verfügt, der (ein Zeiger auf) eine Struktur mit einem flexiblen Arrayelement und der rechte Operand dieses Element ist, verhält er sich so, als ob dieses Element durch das ersetzt würde längstes Array (mit demselben Elementtyp), das die Struktur nicht größer als das Objekt macht, auf das zugegriffen wird; Der Versatz des Arrays soll der des flexiblen Array-Elements bleiben, selbst wenn dieser sich von dem des Ersatz-Arrays unterscheidet. Wenn dieses Array keine Elemente hätte, verhält es sich so, als hätte es ein Element, aber das Verhalten ist nicht definiert, wenn versucht wird, auf dieses Element zuzugreifen oder einen darüber liegenden Zeiger zu generieren.
Bedeutet das, dass ich nicht darauf zugreifen kann? –
@Alan: Nein, Sie können immer noch auf 'b' zugreifen. – kennytm
@Alan: nein; Es bedeutet nur, dass sizeof() das von Ihnen beobachtete Ergebnis zurückgibt. –
ist, weil der zweite eine struct flexibles Element Array verwendet.Erklärung der Größe des Ergebnisses ist in Wikipedia.
void * b[];
ist ungültig in C89
, so bedeutet es, dass Sie einen C99
Compiler verwenden.
C99
führte ein Mittel, um die „struct Hack“ zu definieren: Es ist jetzt „flexible Anordnungs-Element“ genannt wird und vor dem ihm zugeordneten Speicher vorhanden ist, dessen Größe gleich 0.
Dies ist auch wichtig zu beachten, weil ich versucht habe, bei C89 zu bleiben. Vielen Dank! –
Da die erste ist, keinen Platz für erklärt die Zeiger in "b".
A [Diskussion der Legalität des "struct hack" in ansi c] (http://stackoverflow.com/questions/3711233/). Die Suche nach "struct hack" auf Also gibt nicht viel Interesse zurück, aber das ist der Satz, den Sie suchen. – dmckee