Advanced Java Services | malloc calloc realloc free |
Die Deklarationen dieser Fun ktionen sind in stdlib.h. Mit malloc und calloc fordert man Speicher auf dem Heap an, bei realloc übergibt man einen erhaltenen Speicherblock und fordert einen neuen an, in der Regel einen größeren. Alle drei Funktionen geben einen Pointer vom Typ void* zurück. Obwohl nicht notwendig ist es guter Stil, den Pointer auf den Zieldatentyp zu casten. Falls die Speicheranforderung mißlingt wird NULL zurückgegeben. Mit free schließlich gibt man erhaltenen Speicher wieder frei.
Der von malloc gelieferte Speicherblock ist nicht initialisiert, die Inhalte der Speichereinheiten sind zufällige Werte.
void mallocDemo() { puts("mallocdemo"); int* ipoi = (int*) malloc(10 * sizeof(int)); if (ipoi == NULL) return; int i = 0; for (i = 0; i < 10; ++i) { printf("%d\t", *(ipoi + i)); } printf("\n"); free(ipoi); }
Die Ausgabe kann so aussehen:
mallocdemo 4083024 4063608 1835102823 1701603654 977485171 1869762652 1835102823 1197237613 1768254821 1835103086
Anders bei calloc, hier ist der gelieferte Speicher mit Nullen vorbelegt. Im folgenden wird der gelieferte Speicher einmal als Typ int*, dann als Typ double*.
void callocDemo() { puts("callocdemo"); int i = 0; int* ipoi = (int*)calloc(10, sizeof(int)); // anzahl = 10, größe einer einheit = 4 for (i = 0 ; i <10 ; ++i) { printf("%d\t", *(ipoi + i)); } printf("\n"); // gleichen Speicherblock als 5 double auffassen double* dpoi = (double*)ipoi; for (i = 0 ; i < 5 ; ++i) { printf("%d\t", *(ipoi + i)); } printf("\n"); free(ipoi); }
Die Ausgabe
callocdemo 0 0 0 0 0 0 0 0 0 0 0.000000 0.000000 0.000000 0.000000 0.000000
Hier muß man drei Fälle unterscheiden, zwei falls die Speicheranforderung erfolgreich war und einen falls die Speicheranforderung nicht erfolgreich war.
Das folgende Beispiel demonstriert diese Möglichkeiten.
void reallocDemo() { puts("reallocdemo"); int* ipoi1 = (int*)malloc(4000); if(ipoi1 == NULL) return; *ipoi1 = 17; printf("ipoi1 = %p wert = %d\n\n", ipoi1, *ipoi1); int* ipoi2 = (int*)realloc(ipoi1, 5000); reallocMessage(ipoi1, ipoi2); int* ipoi3 = (int*)realloc(ipoi2, 6000); reallocMessage(ipoi2, ipoi3); int* ipoi4 = (int*)realloc(ipoi3, 60000000000); reallocMessage(ipoi3, ipoi4); free(ipoi1); } void reallocMessage(void* pOldMem, void* pNewMem) { if (pNewMem != NULL && pOldMem == pNewMem) { printf("old = %p new = %p wert = %d\n", pOldMem, pNewMem, *(int*)pNewMem); printf("new memory, old pointer\n\n"); } else if (pNewMem != NULL && pOldMem != pNewMem) { printf("old = %p new = %p wert = %d\n", pOldMem, pNewMem, *(int*)pNewMem); printf("new memory, new pointer, free old memory\n\n"); } else // pNewMem == NULL { printf("old = %p new = %p wert = %d\n", pOldMem, pNewMem, *(int*)pOldMem); printf("no new memory, old memory untouched\n\n"); } }
Eine mögliche Auasgabe
reallocdemo ipoi1 = 003E4D50 wert = 17 old = 003E4D50 new = 003E5CF8 wert = 17 new memory, new pointer, free old memory old = 003E5CF8 new = 003E5CF8 wert = 17 new memory, old pointer old = 003E5CF8 new = 00000000 wert = 17 no new memory, old memory untouched
Die Verwendung von free wurde schon gezeigt. Falls NULL übergeben wird, macht free nichts. Wird Speicher freigegeben bleibt der Wert des (nun ungültigen) Pointers erhalten, da free ihn nicht auf NULL setzen kann.