Gibt es Größenbeschränkungen für C-Strukturen?
Gibt es Größenbeschränkungen für C-Strukturen?
Nemo
Alexej Frunze
Aus dem C-Standard:
5.2.4.1 Übersetzungsgrenzen
1 Die Implementierung muss in der Lage sein, mindestens ein Programm zu übersetzen und auszuführen, das mindestens eine Instanz jeder der folgenden Grenzen enthält:
… — 65535 Bytes in einem Objekt (nur in einer gehosteten Umgebung)
… — 1023 Mitglieder in einer einzigen Struktur oder Gewerkschaft
… — 63 Ebenen verschachtelter Struktur- oder Union-Definitionen in einer einzigen Struktur-Deklarations-Liste … 13) Implementierungen sollten es vermeiden, feste Übersetzungsgrenzen aufzuerlegen, wann immer dies möglich ist.
Ansonsten gilt die Obergrenze SIZE_MAX
(Maximalwert für size_t
).
Blagovest Buyukliev
Seit der sizeof
Operator liefert ein Ergebnis vom Typ size_t
sollte die Grenze sein SIZE_MAX
.
Sie können den Wert bestimmen SIZE_MAX
so was:
#include <stdint.h>
#include <stdio.h>
int main (void) {
printf("%zu", SIZE_MAX);
return 0;
}
Das sollte der Compiler zulassen. Was die Laufzeitumgebung zulässt, ist eine andere Geschichte.
Das Deklarieren eines ähnlich großen Objekts auf dem Stapel (lokal) funktioniert in der Praxis nicht, da der Stapel wahrscheinlich viel, viel kleiner ist als SIZE_MAX
.
Ein solches Objekt global zu haben, könnte dazu führen, dass sich der ausführbare Lader beim Programmstart beschwert.
-
Können Sie sagen, was der wahrscheinliche Wert von SIZE_MAX ist? ist es betriebssystemabhängig? Ich möchte den genauen Wert wissen.
– Nemo
11. Oktober 2011 um 10:54 Uhr
-
Ich bin wirklich neugierig, welche Größe Sie verwenden möchten und warum. Erzähl uns?
– Jo
11. Oktober 2011 um 10:55 Uhr
-
Zumindest in der Theorie. In der Praxis ist die Grenze der Arbeitsspeicher im Computer, der viel kleiner ist als
SIZE_MAX
auf einem modernen 64-Bit-Computer.– Irgendein Programmierer-Typ
11. Oktober 2011 um 10:57 Uhr
-
@Nemo Überprüfen Sie die Headerdatei stdint.h, sie sollte dort sein.
– Irgendein Programmierer-Typ
11. Oktober 2011 um 10:57 Uhr
-
@Nemo: SIZE_MAX ist Compiler-/Architektur-abhängig, also im Allgemeinen auch OS-abhängig. Siehe seine Definition in stdint.h (oder, falls nicht vorhanden, möglicherweise in limits.h) in den Header-Dateien Ihres Compilers.
– Alexey Frunze
11. Oktober 2011 um 11:02 Uhr
Empirische Analyse
In der Praxis scheinen Implementierungen wie GCC nur Strukturen kleiner als zuzulassen size_t
vielleicht gebunden durch PTRDIFF_MAX
. Siehe auch: Was ist die maximale Größe eines Arrays in C?
Verwendung:
for i in `seq 32`; do printf "typedef struct { S$i x; S$i y; } S$(($i+1));\n"; done
Wir machen das Programm:
#include <stdint.h>
#include <stdio.h>
typedef struct { uint8_t i; } S0;
typedef struct { S0 x; S0 y; } S1;
typedef struct { S1 x; S1 y; } S2;
typedef struct { S2 x; S2 y; } S3;
typedef struct { S3 x; S3 y; } S4;
typedef struct { S4 x; S4 y; } S5;
typedef struct { S5 x; S5 y; } S6;
typedef struct { S6 x; S6 y; } S7;
typedef struct { S7 x; S7 y; } S8;
typedef struct { S8 x; S8 y; } S9;
typedef struct { S9 x; S9 y; } S10;
typedef struct { S10 x; S10 y; } S11;
typedef struct { S11 x; S11 y; } S12;
typedef struct { S12 x; S12 y; } S13;
typedef struct { S13 x; S13 y; } S14;
typedef struct { S14 x; S14 y; } S15;
typedef struct { S15 x; S15 y; } S16;
typedef struct { S16 x; S16 y; } S17;
typedef struct { S17 x; S17 y; } S18;
typedef struct { S18 x; S18 y; } S19;
typedef struct { S19 x; S19 y; } S20;
typedef struct { S20 x; S20 y; } S21;
typedef struct { S21 x; S21 y; } S22;
typedef struct { S22 x; S22 y; } S23;
typedef struct { S23 x; S23 y; } S24;
typedef struct { S24 x; S24 y; } S25;
typedef struct { S25 x; S25 y; } S26;
typedef struct { S26 x; S26 y; } S27;
typedef struct { S27 x; S27 y; } S28;
typedef struct { S28 x; S28 y; } S29;
typedef struct { S29 x; S29 y; } S30;
/*typedef struct { S30 x; S30 y; } S31;*/
S30 s;
int main(void) {
printf("%jx\n", (uintmax_t)sizeof(s));
return 0;
}
und dann in Ubunbu 17.10:
$ arm-linux-gnueabi-gcc --version
arm-linux-gnueabi-gcc (Ubuntu/Linaro 7.2.0-6ubuntu1) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ arm-linux-gnueabi-gcc -std=c99 main.c
funktioniert. Aber wenn wir auskommentieren S31
es schlägt fehl mit:
main.c:35:16: error: type ‘struct <anonymous>’ is too large
typedef struct { S30 x; S30 y; } S31;
Die maximale Größe liegt also zwischen 2^30 und (2^31 – 1).
Dann können wir konvertieren S30
zu:
typedef struct { S29 x; S29 y; uint8_t a[(2lu << 29) - 1]; } S30;
und damit stellen wir fest, dass die maximale Größe tatsächlich ist 2^31 - 1 == PTRDIFF_MAX
zu dieser Implementierung.
Meinen Sie die physische Größe im Speicher oder die Anzahl der Mitglieder?
– Irgendein Programmierer-Typ
11. Oktober 2011 um 10:50 Uhr
Physische Größe im Speicher.
– Nemo
11. Oktober 2011 um 10:51 Uhr
Wenn Sie diese Überlegung haben, ist die Verwendung einer Struktur vielleicht der falsche Weg?
– AndersK
11. Oktober 2011 um 10:58 Uhr
ja, physische Größe im Speicher.
– Scott.N
22. März 2013 um 10:15 Uhr