3.8 Speicherbedarf mit sizeof ermitteln
Wenn Sie die Größe eines Typs benötigen, müssen Sie den sizeof-Operator verwenden. Dieser gibt in der Regel die Größe des Operanden in Bytes zurück und wird beispielsweise bei der dynamischen Speicherreservierung verwendet oder dann, wenn Sie Programme schreiben, die auf andere Plattformen portierbar sind. Als Rückgabetyp von sizeof ist size_t definiert. size_t ist ein implementierungsabhängiger unsigned-Ganzzahlentyp und in der Header-Datei stddef.h (und anderen Header-Dateien) definiert. Wie viel Speicherplatz ein Variablentyp letztlich benötigt, hängt von seiner Implementierung ab. Die Formatanweisung für size_t lautet %zu. Beachten Sie, dass sizeof ein echter Operator ist und dass der entsprechende Größenwert auch nicht durch eine Funktion ermittelt wird.
Listing 3.2 enthält ein einfaches Beispiel, in dem der sizeof-Operator verwendet wird:
00 // Kapitel3/sizeof_beispiel.c
01 #include <stdio.h>
02 int main(void) {
03 int ival = 0;
04 double dval = 0;
05 printf("sizeof(ival) : %zu\n", sizeof(ival));
06 printf("sizeof(dval) : %zu\n", sizeof(dval));
07 // So geht es auch
08 printf("sizeof(float) : %zu\n", sizeof(float));
09 size_t sz = sizeof(char);
10 printf("sizeof(char) : %zu\n", sz);
11 return 0;
12 }
Listing 3.2 Das Listing demonstriert die Verwendung des »sizeof«-Operators mit Variablen unterschiedlichen Typs.
Das Programm sieht bei der Ausführung auf unserem System folgendermaßen aus:
sizeof(ival) : 4
sizeof(dval) : 8
sizeof(float) : 4
sizeof(char) : 1
[»] Speicherausrichtung eines Operanden ermitteln
Seit C11 gibt es den Operator _Alignof, mit dem Sie die Speicherausrichtung des Operanden ermitteln können. Dieser Operator ist auch als Makro mit alignof vorhanden, damit Sie ihn etwa mit alignof(long double) so komfortabel wie schon den sizeof-Operator verwenden können. Wie der sizeof-Operator liefert auch alignof die Speicherausrichtung des Operanden vom Typ size_t zurück.
Die Speicherausrichtung (das sogenannte Alignment) ist die Ausrichtung von Speicherobjekten an den Wortgrenzen des Prozessors. Die Breite eines Datenwortes ist meistens die Anzahl der Bits, die maximal in ein Prozessorregister passen. Wenn Sie also einen modernen 64-Bit-Prozessor haben, fangen sämtliche Speicherobjekte an Adressen an, die durch 8 teilbar sind. Hierdurch wird zwar Platz vergeudet, aber die Ausführungsgeschwindigkeit enorm erhöht.
Bei den meisten Compilern können Sie das Alignment auch abschalten und erhalten dadurch kompakteren Code. Allerdings verlangen manche Prozessoren, wie z. B. der im Amiga verbaute 68000-Prozessor, dass sämtliche Speicherobjekte an geraden Adressen anfangen. ARM-Prozessoren (z. B. beim Raspberry Pi) verlangen sogar, dass sämtliche Speicheradressen von Speicherobjekten durch 4 teilbar sind.
Im Endeffekt bedeutet dies: Lassen Sie die Finger von den Alignment-Einstellungen! So ersparen Sie sich böse Systemabstürze, für die sich einfach kein Grund finden lässt.