Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

 << zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch für Linux, Unix und Windows
– 2., aktualisierte und erweiterte Auflage 2006
Buch: C von A bis Z

C von A bis Z
1.116 S., mit CD, Referenzkarte, 39,90 Euro
Galileo Computing
ISBN 3-89842-643-2
gp Kapitel 16 Dynamische Speicherverwaltung
  gp 16.1 Das Speicherkonzept
  gp 16.2 Speicheralloziierung mit malloc()
  gp 16.3 Die Mysterie von NULL
    gp 16.3.1 NULL für Fortgeschrittene
    gp 16.3.2 Was jetzt – NULL, 0 oder \0 ... ?
    gp 16.3.3 Zusammengefasst
  gp 16.4 Speicherreservierung und ihre Probleme
  gp 16.5 free() – Speicher wieder freigeben
  gp 16.6 Die Freispeicherverwaltung
    gp 16.6.1 Prozessinterne Freispeicherverwaltung
  gp 16.7 Dynamisches Array
  gp 16.8 Speicher dynamisch reservieren mit realloc und calloc
  gp 16.9 Speicher vom Stack anfordern mit alloca (nicht ANSI C)
  gp 16.10 free – Speicher wieder freigeben
  gp 16.11 Zweidimensionale dynamische Arrays
  gp 16.12 Wenn die Speicheralloziierung fehlschlägt
    gp 16.12.1 Speicheranforderung reduzieren
    gp 16.12.2 Speicheranforderungen aufteilen
    gp 16.12.3 Einen Puffer konstanter Größe verwenden
    gp 16.12.4 Zwischenspeichern auf Festplatte vor der Alloziierung
    gp 16.12.5 Nur so viel Speicher anfordern wie nötig


Galileo Computing - Zum Seitenanfang

16.2 Speicheralloziierung mit malloc()  toptop

Es wurde bereits kurz erwähnt, mit welcher Funktion Speicher dynamisch reserviert werden kann. Es wird dabei auch von einer Speicheralloziierung (allocate, dt. zuweisen) gesprochen. Hier die Syntax dieser Funktion:

#include <stdlib.h>
void *malloc(size_t size);

Bei erfolgreichem Aufruf liefert die Funktion malloc() die Anfangsadresse der Größe size Bytes vom Heap zurück. Da die Funktion einen void-Zeiger zurückliefert, ist diese nicht abhängig von einem Datentyp. Hierzu ein Beispiel:

/* malloc1.c */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
   int *p;
   p = (int *)malloc(sizeof(int));
   if(p != NULL) {
      *p=99;
      printf("Alloziierung erfolgreich ... \n");
   }
   else {
      printf("Kein Virtueller RAM mehr verfügbar ...\n");
      return EXIT_FAILURE;
   }
   return EXIT_SUCCESS;
}

Nach der Deklaration eines int-Zeigers wurde diesem mit

p = (int *)malloc(sizeof(int));

eine Anfangsadresse eines Speicherbereichs der Größe int zugewiesen. Bei Erfolg zeigt der Zeiger p auf den Anfang des reservierten Speicherbereichs. Ist dabei etwas schief gegangen, zeigt der Zeiger auf NULL, und es wird ausgegeben, dass kein Speicherplatz reserviert werden konnte. Hierzu der Programmablauf bildlich (siehe Abbildung 16.1).


Hinweis   Das Typencasting der Funktion malloc() ist in C nicht notwendig und kann auch weggelassen werden. ANSI C++ schreibt allerdings ein Casten des Typs void * vor. Zwar halten Sie hier ein C-Buch in den Händen, aber häufig ist der Compiler auf C++-Projekten eingestellt. Es gilt also auch hier selbiges, was bereits beim void-Zeiger in Abschnitt 14.11 beschrieben wurde. Blättern Sie ggf. zu diesem Abschnitt zurück.


Abbildung
Hier klicken, um das Bild zu Vergrößern

Abbildung 16.1   Dynamisch reservierter Speicher vom Heap

Na gut, ich denke, das beeindruckt Sie nicht besonders. Zur Laufzeit eines Programms Speicherplatz für einen int-Wert reservieren mit solch einem Aufwand? Gut, dann reservieren Sie eben mehr Speicherplatz für mehrere int-Werte:

p = (int *)malloc(2 * sizeof(int));

Hiermit reservieren Sie Speicherplatz für zwei int-Werte vom Heap. Das Beispiel als Listing:

/* malloc2.c */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
   int *p = (int *)malloc(2 * sizeof(int));
   if(p != NULL) {
      *p=99;         /* Alternativ auch p[0] = 99  */
      *(p+1) = 100;  /* Alternativ auch p[1] = 100 */
      printf("Alloziierung erfolgreich ... \n");
   }
   else {
      printf("Kein Virtueller RAM mehr verfügbar ...\n");
      return EXIT_FAILURE;
   }
   printf("%d %d\n", p[0], p[1]);
   /* Sie können die Werte auch so ausgeben lassen */
   printf("%d %d\n", *p, *(p+1));
   return EXIT_SUCCESS;
}

Folgende Abbildung soll den Sachverhalt veranschaulichen:

Abbildung
Hier klicken, um das Bild zu Vergrößern

Abbildung 16.2   Speicher für mehrere Elemente dynamisch anfordern

Der Sachverhalt, warum *p und p[0] oder *(p+1) und p[1] auf dasselbe Element zugreifen, wurde in Kapitel 14, Zeiger, geklärt. Blättern Sie notfalls einfach zu den Tabellen am Ende des Kapitels 14 zurück.

 << zurück
  
  Zum Katalog
Zum Katalog: C von A bis Z
C von A bis Z
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Shell-Programmierung






 Shell-Programmierung


Zum Katalog: Linux-UNIX-Programmierung






 Linux-UNIX-Programmierung


Zum Katalog: C/C++






 C/C++


Zum Katalog: UML 2.0






 UML 2.0


Zum Katalog: Reguläre Ausdrücke






 Reguläre Ausdrücke


Zum Katalog: Linux






 Linux


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo





Copyright © Galileo Press 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de