Dynamische Speicherverwaltung In C, Pointer, Calloc, Malloc, Realloc, Free

(zusammengestellt aus C und C++ - Programmierung und Referenz, ISBN 3-8272-5066-8)

Zeiger alias Pointer

Initialisierung

Die Initialisierung eines Zeigers erfolgt durch die Zuweisung einer Adresse und eines mit der Adresse verbundenen Speicherbereichs. Die Initialisierung kann auf verschiedene Weisen geschehen:
  • Zuweisung einer Adresse eines existierenden Objekts.
    • Die Adresse einer Variablen kann ueber den Adress-Operator & ermittelt werden
    • Zeiger sind selbst Adressen
    • Die Namen von Arrays und Funktionen stellen ebenfalls Adressen dar.
  • Zuweisung von NULL. Zeiger, die auf kein Objekt gerichtet sind, sollten mit der *NULL*-Adresse initialisiert werden. Auf diese Weise kann leicht getestet werden, ob der Zeiger auf ein Objekt zeigt oder nicht.
  • Allokation durch malloc() oder new. Die Funktion malloc() sowie der C++-Operator new dienen dazu, Speicher zu reservieren und die Adresse an den Zeiger zu übergeben. Auf diese Weise werden Objekte eingerichtet, die nur über Zeiger erreichbar sind.
  • Beispiel
int x; int *px = &x;
int *py; py = px;
int array[10]; int *parray = NULL; parray = array;

  • Nicht initialisierte Zeiger enthalten undefinierte Bitmuster, die bei der Dereferenzierung als Adresse interpretiert werden. Dies führt unweigerlich zu Programmfehlern und oftmals zu Programmabstürzen. Durch folgende Vorsichtsmaßnahmen kann man sich dagegen schützen.
    • Zeiger stets direkt bei der Deklaration initialisieren, oder zumindest auf NULL setzen.
    • An wichtigen Programmstellen abtesten ob ein Zeiger eine Adresse enthaelt oder auf NULL zeigt.

Dynamische Speicherverwaltung - Speicherallokation

Die dynamische Speicherverwaltung ist ein wichtiges Einsatzgebiet von Zeigern. Mittels der C++Operatoren new und delete oder auch der C-Funktion malloc() und free() kann Speicherplatz je nach Bedarf angefordert und wieder frei gegeben werden. Bei dieser Form der Initialisierung wird dem Zeiger bisher nicht belegter Speicherplatz zugewiesen.

  • Beispiel p_int = (int*) malloc(n*sizeof(int));

Dynamische Speicherverwaltung - Freigabe von Speicher

Die Funktionen free() und der C++-Operator delete dienen dazu, den mit einem Zeiger assoziierten Speicherplatz freizugeben. Die Zeigervariable bleibt dabei erhalten und kann erneut initialisiert werden. Dynamisch allokierter Speicherplatz muss entweder vom Programmierer explizit freigegeben werden oder bleibt bis zum Programmende reserviert.
  • Beispiel
void main() { p_int = (int*) malloc(sizeof(int)); free(p_int); }

  • Bei der dynamischen Speicherplatzreservierung wird die Anfangsadresse des Speicherbereiches an einen Zeiger übergeben. Zwei Situationen können dazu führen, dass dieser Zeiger verloren geht und der Speicherplatz nicht mehr freigegeben werden kann:
    • Wurde die Adresse einer lokalen Zeigervariable zugewiesen, verfällt diese, wenn ihr Gültigkeitsbereich verlassen wird, der dynamisch allokierte Speicherbereich bleibt erhalten.
    • Wird dem Zeiger eine andere Adresse zugewiesen und wurde versäumt, die Adresse des Speicherplatzes in einem anderen Zeiger zu speichern, ist der Speicherbereich ebenfalls nicht mehr adressierbar.

  • Die beiden Konzepte new / delete und malloc() / free() sollten nicht vermischt werden, d.h. ein Speicherbereich, der mit malloc() reserviert wurde, sollte auch mit free() freigegeben werden, nicht mit delete.

spezielle Zeiger

Zeiger auf Zeichenketten char*

Ein Zeiger vom Typ char* weist auf ein einzelnes Zeichen. Viele Bibliotheksfunktionen, die Zeichenketten verarbeiten (strcpy(), strlen(), etc.) erwarten als Argument solch einen Zeiger auf das erste Zeichen der zu verarbeitenden Zeichenkette. Die so übergebene Zeichenkette beginnt mit der Adresse, die der Zeiger liefert, und endet mit dem ersten Auftauchen des Nullzeichens '\0' .
  • Bei der Verwendung der entsprechenden Bibliotheksfunktionen ist daher darauf zu achten, dass die übergebenen Zeiger auch stets auf null terminierte Zeichenketten verweisen, da es ansonsten zu unerwünschten Speicherzugriffen - meist begleitet von Programmabstürzen - kommt.

Routinen

calloc

  • <stdlib.h>, <cstdlib.h>
Mit calloc() kann Speicherplatz für ein Array, dessen Speicherbedarf unter 64 kByte liegt, angefordert werden. Das angelegt Array wird für anzahl Elemente der Groesse groesse eingerichtet und mit Nullen initialisiert.

void *calloc(size_t anzahl, size_t groesse)

  • Rückgabe: void Zeiger auf Speicherbereich oder NULL Zeiger, wenn Speicher nicht allokiert werden konnte.

Beispiel

puffer = (char*) calloc(20,40);

malloc

  • <stdlib.h>, <cstdlib.h>
Die Funktion malloc() fordert einen Speicherblock von der übergebenen Groesse groesse an. Der von der Funktion zurueck gegebene Zeiger ist vom Typ *void und muss mit einer *cast*-Anweisung in den gewünschten Typ umgewandelt werden.

void* malloc(size_t groesse)

  • Rückgabe: void Zeiger auf Speicherbereich oder NULL Zeiger, wenn Speicher nicht allokiert werden konnte.

Beispiel

puffer = (char*) calloc(20,40); intpointer = (int*) malloc (90 * sizeof(int)); if (intpointer == NULL) { printf("Speicher konnte nicht zugeordnet werden.\n"); }

realloc

  • <stdlib.h>, <cstdlib.h>
Die Funktion malloc() kann die Groesse eines zuvor mit malloc() oder calloc() angeforderten Speicherblocks (puffer) angepasst werden auf die Groesse groesse. Der Inhalt des alten Speicherblocks bleibt dabei erhalten, seine Adresse kann sich jedoch ändern.

void* realloc(void *puffer, size_t groesse)

  • Rückgabe: Die Funktion gibt einen void Zeiger zum neu zugeordneten Speicherblock zurück oder einen NULL Zeiger, wenn Speicher nicht eingerichtet werden konnte.

free

  • <stdlib.h>, <cstdlib.h>
Die Funktion gibt den Speicherbereich frei, auf den addr verweist und der zuvor mit einer der Funktionen malloc(), calloc() oder realloc() angefordert wurde.

void free(void* addr)

  • Der Funktion kann auch ein Zeiger auf NULL übergeben werden, in welchem Falle jedoch kein Code ausgeführt wird.

-- PeterZumbruch - 28 Nov 2006
Topic revision: r2 - 2006-11-28, PeterZumbruch
 
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding GSI Wiki? Send feedback
Imprint (in German)
Privacy Policy (in German)