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.5 free() – Speicher wieder freigeben  toptop

Wenn Sie Speicher vom Heap angefordert haben, sollten Sie diesen auch wieder zurückgeben. Der alloziierte Speicher wird mit folgender Funktion freigegeben:

#include <stdlib.h>
void free (void *p)

Der Speicher wird übrigens auch ohne einen Aufruf von free() freigegeben, wenn sich das Programm beendet.


Hinweis   Zwar wird generell behauptet (und ist auch meistens der Fall), dass bei der Beendigung eines Programms das Betriebssystem den reservierten und nicht mehr freigegebenen Speicher selbst organisiert und somit auch wieder freigibt, aber dies ist nicht vom ANSI/ISO-Standard gefordert.

Somit ist dies also abhängig von der Implementation der Speicherverwaltung des Betriebssystems.


Ein Beispiel zu free():

/* free1.c */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
   int *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;
   }
   if(p != NULL)
      free(p);
   return EXIT_SUCCESS;
}

Es wird hier auch überprüft, dass nur wirklich reservierter Speicherplatz wieder freigegeben wird. Der mit free() freigegebene Speicherplatz wird danach zwar als frei markiert, aber p zeigt immer noch auf die ursprüngliche Speicherstelle. Hier das Beispiel:

/* free2.c */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
   int *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;
   }
   printf("vor free() *p = %d\n", *p);
   if(p != NULL)
      free(p);
   printf("nach free() *p = %d\n", *p);
   return EXIT_SUCCESS;
}

Hinweis   Da der Heap üblicherweise aus Performancegründen nicht wieder reduziert wird, konnten Sie wie hier im Beispiel eventuell auf den freigegebenen Speicherplatz und dessen Inhalt wieder zugreifen. Aber dieses Verhalten ist nicht »portabel« und wird auch nicht vom ANSI C Standard gefordert. Sofern Sie also vorhaben, so etwas absichtlich in der Praxis auszuführen (warum auch immer), ist das Verhalten undefiniert.


Wollen Sie absolut sicher sein, dass der Zeiger nichts mehr zurückgibt, dann übergeben Sie dem Zeiger nach der Freigabe von Speicher einfach den NULL-Zeiger:

free(p);
p = NULL;

Dies können Sie in ein Makro wie folgt verpacken:

#define my_free(x)  free(x); x = NULL

Internes   Die Speicherverwaltung merkt sich die Größe eines jeden Speicherblocks, der von Ihnen angefordert wurde – daher ist es auch nicht nötig, die Größe des Blocks (als echte Bytegröße) anzugeben, um den Speicher mit free() wieder freizugeben. Leider gibt es daher allerdings auch keinen portablen Weg, zu erfahren, wie groß dieser Speicherblock denn tatsächlich ist.


Was malloc() und die weiteren Speicheralloziierungs-Funktionen so bedeutend und wichtig macht, ist die Möglichkeit, von jedem beliebigen Datentyp Speicher anfordern zu können – sind es nun einfache Datentypen wie Strings, Arrays oder komplexe Strukturen.

Natürlich können Sie auch Speicherplatz für ein char-Array zur Laufzeit anfordern. Das folgende Beispiel demonstriert dies:

/* malloc4.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUF 80
int main(void) {
   char puffer[BUF];
   char *dyn_string;
   printf("Ein Text mit max. 80 Zeichen: ");
   fgets(puffer, BUF, stdin);
   dyn_string = (char *)malloc(strlen(puffer) + 1);
   if(dyn_string != NULL)
      strncpy(dyn_string, puffer, strlen(puffer) + 1);
   else {
      printf("Konnte keinen Speicherplatz reservieren\n");
      return EXIT_FAILURE;
   }
   printf("%s",dyn_string);
   free(dyn_string);
   return EXIT_SUCCESS;
}

Wobei erwähnt werden muss, dass diese Art, dynamisch Speicher für einen Text zu reservieren, noch recht unflexibel ist. Mit

dyn_string = (char *)malloc(strlen(puffer) + 1);

wird exakt so viel Speicher angefordert wie zuvor mit fgets() in den String puffer eingelesen wurde. Im Verlauf des Buchs werden Sie erfahren, wie Sie viel effektiver dynamischen Speicher für Text anfordern. Denn bei diesem Beispiel hätten Sie es ja gleich beim char-Array puffer belassen können.

 << 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