16.4 Speicherreservierung und ihre Probleme
 
Bei einem Aufruf der Funktion malloc() muss die Größe des zu reservierenden Speichers in Bytes angegeben werden. Damit ist die Größe des Speicherobjekts gemeint, das durch einen Zeiger referenziert werden soll. Für die dynamische Speicherzuweisung haben Sie folgende drei Möglichkeiten:
|
Als numerische Konstante: |
|
p = (int *)malloc(sizeof(2)); |
|
|
|
Hiermit werden vier Bytes (!) reserviert, auf deren Anfangsadresse der Zeiger p verweist. Es werden nicht – wie vielleicht irrtümlicherweise angenommen – zwei Bytes reserviert, sondern es wird eben soviel Speicher reserviert, wie es dem Datentyp im sizeof-Operator auf dem entsprechenden System entspricht. Der Wert 2 entspricht gewöhnlich auf 32-Bit-Rechnern 4 Bytes (int). Somit kann die Verwendung einer nummerischen Konstanten sehr verwirrend sein. |
|
|
|
Die Angabe des Datentyps mithilfe des sizeof-Operators: |
|
p = (int *)malloc(sizeof(int)); |
|
|
|
Diese Möglichkeit hat einen Nachteil. Was ist, wenn Sie statt int-Werten auf einmal double-Werte benötigen? Dann müssen Sie mühsam alle Speicherzuweisungen ändern in: |
|
|
|
p = (double *)malloc(sizeof(double)); |
|
|
|
Den dereferenzierten Zeiger selbst für den sizeof-Operator verwenden: |
|
p = (double *)malloc(sizeof(*p)); |
|
|
|
Aber Achtung: Wehe, der Dereferenzierungsoperator (*) wird wie in folgendem Listing vergessen: |
|
|
/* malloc3.c */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
double *p1,*p2;
p1 = (double *)malloc(sizeof(p1)); // Fehler
p2 = (double *)malloc(sizeof(p2)); // Fehler
if(p1 != NULL && p2 != NULL) {
*p1 = 5.15;
printf("p1 = %f\n",*p1);
*p2 = 10.99;
printf("p2 = %f\n",*p2);
}
return EXIT_SUCCESS;
}
Wenn Sie »Glück« haben, stürzt das Programm ab. Im schlimmsten Fall funktioniert das Programm und gibt die richtigen Zahlen aus. Das wäre aber purer Zufall. Denn ohne den Dereferenzierungsoperator wird nicht ein double-Wert an malloc() übergeben, sondern die Größe des Zeigers. Und diese beträgt immer vier (bei 32-Bit-Rechnern) statt der erforderlichen acht Bytes. Wenn jetzt ein anderer Wert an diese Adresse gelangt, ist der weitere Verlauf des Programms nicht absehbar. Es kommt zu einer so genannten Überlappung der Speicherbereiche.
|