8.5 Freier Speicher

Zusätzlich zu den fest vereinbarten Variablen kann ein Programm zur Laufzeit bei Bedarf Speicher anfordern (allokieren), in dem es ebenfalls Daten unterbringen kann. Siehe dazu die Funktionen malloc(), calloc(), realloc(), und free().

Beim Aufruf von malloc() gibt man die gewünschte Speichermenge an und erhält einen Zeiger auf einen entsprechend großen freien Speicher. Diesen Speicher kann man nur über Zeiger beschreiben und lesen, aber ansonsten wie eine Variable behandeln. Ist beim Aufruf von malloc() kein ausreichend großer Speicherblock frei, dann liefert malloc() den ungültigen Zeiger NULL zurück.

Die gewünschte Speichermenge muß man in der Einheit Byte angeben. Wie erfährt man jetzt aber, wieviele Byte man für beispielsweise 10 Elemente vom Typ int benötigt? Je nach Rechner wird eine int in 2, 4 oder 8 Byte gespeichert. Dementsprechend müßte man malloc(20), malloc(40) oder malloc(80) aufrufen, um die richtige Speichermenge zu erhalten. Um dieses Problem rechnerunabhängig zu lösen, gibt es den Operator sizeof. Dahinter kann man in Klammern einen Datentyp oder (mit oder ohne Klammern) eine Variable eintragen und erhält daraus die Größe des entsprechenden Objekts in Byte. Mit malloc( 10*sizeof(int) ) übergibt man als Argument an malloc() auf jedem Rechner die Anzahl Byte, die jeweils für 10 Werte vom Typ int benötigt werden.

sizeof ist keine Funktion, obwohl die Verwendung mit Klammern ähnlich aussieht. Vielmehr wird bereits bei der Übersetzung vom Compiler für den ganzen Ausdruck eine Konstante eingesetzt.

Mit free() kann man einen mit malloc() allokierten Speicherblock wieder freigeben, wenn man ihn nicht mehr benötigt.

Beispiel:

/* damalloc.c 30. 7.95 kw
 * Beispiel fuer malloc().
 */

/* Mit #include wird an dieser Stelle der Inhalt der Datei
 * stdlib.h eingefuegt. Dies deshalb, weil darin die
 * Funktion malloc() vereinbart ist.
 */

#include <stdlib.h>

main()
{
  double *feld;   /* Vereinbarung der Variablen feld.
                   * feld hat nicht den Typ double
                   * (doppelt genaue Gleitkommazahl),
                   * sondern double* (Zeiger auf eine
                   * Gleitkommazahl), kann also die
                   * Adresse einer double speichern.
                   */

  /* mit malloc() Platz fuer 10 double-Elemente holen:
   * malloc() reserviert in einem unbenutzten
   * Speicherbereich des Rechners Platz fuer 10 Werte
   * der Groesse, die double benoetigt.
   * Wenn genug Platz frei ist, dann liefert malloc()
   * die Adresse des Anfangs des Speicherbereichs.
   * Wenn kein ausreichend grosser Bereich frei ist,
   * liefert malloc() statt einer gueltigen Adresse
   * den Wert NULL (vereinbart in stdlib.h).
   * Die von malloc() gelieferte Adresse wird in der
   * Variablen feld gespeichert, die ja eine Adresse
   * aufnehmen kann.
   */
  feld = malloc( 10*sizeof(double) );

  /* ist die gelieferte Adresse sinnvoll, also ungleich NULL?
   */
  if( feld!=NULL )
  {
    /* hier kann man feld[0] bis feld[9] verwenden
     * ...
     */
    free( feld );  /* Speicher wieder freigeben         */
  }
  else
    puts( "kein Speicher frei!" );       /* Fehler         */
}

AnyWare@Wachtler.de