Eine Einführung in die Programmiersprache C und ... - C /C++ Ecke
Eine Einführung in die Programmiersprache C und ... - C /C++ Ecke
Eine Einführung in die Programmiersprache C und ... - C /C++ Ecke
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
<strong>E<strong>in</strong>e</strong> <strong>E<strong>in</strong>führung</strong> <strong>in</strong> <strong>die</strong> Informatik <strong>und</strong> <strong>die</strong> <strong>Programmiersprache</strong> C<br />
26 Dynamische Speicherverwaltung<br />
Häufig ist beim Schreiben <strong>und</strong> Compilieren e<strong>in</strong>es Programmes nicht bekannt, wieviel Daten dere<strong>in</strong>st<br />
von <strong>die</strong>sem Programm bearbeitet werden. Deshalb ist es bei den <strong>in</strong>ternen Datenstrukturen oft<br />
auch nicht möglich, im Voraus e<strong>in</strong>e vernünftige, fixe Grösse für den Speicherplatz zu wählen.<br />
Man kann natürlich alle Arrays auf Vorrat masslos überdimensionieren (wie zum Beispiel:<br />
char TextVonEditor[1000000]), nur ist damit immer noch nicht garantiert dass nun <strong>in</strong><br />
jedem Fall genügend Platz vorhanden ist, <strong>und</strong> zudem wird dadurch im Normalfall viel zuviel Speicher<br />
verschwendet.<br />
Es muss deshalb möglich se<strong>in</strong>, zu Laufzeit des Programmes Speicher vom Betriebssystem anzufordern<br />
wenn er benötigt wird, <strong>und</strong> <strong>die</strong>sen Speicher auch wieder zurückzugeben wenn er nicht mehr<br />
benutzt wird.<br />
Dieses dynamische Anfordern <strong>und</strong> Freigeben von Speicher bezeichnet man als dynamische Speicherverwaltung.<br />
In C stehen dazu gr<strong>und</strong>sätzlich <strong>die</strong> Funktionen malloc() zum Allozieren von<br />
Speicher, <strong>und</strong> free() zum Freigeben von Speicher zur Verfügung. (Zur Anforderung von Speicher<br />
gibt es für spezielle Fälle noch <strong>die</strong> Funktionen realloc() <strong>und</strong> calloc()). Der Speicherbereich,<br />
aus dem <strong>die</strong>ser dynamisch verwaltete Speicher entnommen wird, bezeichnet man als<br />
'Heap'.<br />
Der Funktion malloc() muss <strong>die</strong> Grösse des gewünschten Speichers übergeben werden, Sie liefert<br />
e<strong>in</strong>en Zeiger auf den nun reservierten Speicherbereich zurück. Wenn das System nicht mehr<br />
genügend Speicher frei hat, um <strong>die</strong> Anforderung zu erfüllen, wird e<strong>in</strong> NULL-Zeiger zurückgegeben.<br />
Es ist deshalb unerlässlich, nach jeder Anforderung von Speicher zu überprüfen, ob man den Speicher<br />
auch erhalten hat.<br />
Mit der Funktion realloc() kann e<strong>in</strong> bereits reservierter Speicherblock 'erweitert' werden. Dabei<br />
wird vom System e<strong>in</strong> neuer Block mit der neuen Grösse reserviert, soviel Daten wie möglich (Maximal<br />
soviel wie der neue Block aufnehmen kann, resp. im alten enthalten ist) vom alten Block <strong>in</strong><br />
den neuen Block kopiert, der alte Block freigegeben <strong>und</strong> e<strong>in</strong> Zeiger auf den neuen Block zurückgeliefert.<br />
Der Funktion muss e<strong>in</strong> Zeiger auf den alten Block, sowie <strong>die</strong> gewünschte neue Grösse mitgegeben<br />
werden. Diese Funktion liefert ebenfalls e<strong>in</strong>en NULL Zeiger zurück, wenn der angeforderte<br />
Speicher nicht zur Verfügung gestellt werden konnte (Der alte Block wird <strong>in</strong> <strong>die</strong>sem Fall aber nicht<br />
freigegeben). Diese Funktion kann auch nachgebildet werden, <strong>in</strong>dem man das Allozieren, Kopieren<br />
<strong>und</strong> Freigeben selbst programmiert, nur kann realloc <strong>in</strong> gewissen Fällen effizienter se<strong>in</strong> (Wenn z.B.<br />
der Speicher h<strong>in</strong>ter <strong>die</strong>sem Block noch frei ist, kann der Block e<strong>in</strong>fach erweitert werden, <strong>und</strong> es<br />
muss nichts kopiert werden.)<br />
Wenn man e<strong>in</strong>en reservierten Speicherblock nicht mehr benötigt, muss man ihn mit der Funktion<br />
free() wieder freigeben, damit er anderen Programmen zur Verfügung gestellt werden kann. Der<br />
Funktion free() muss man den Zeiger auf den freizugebenden Speicherblock übergeben (Derselbe<br />
Zeiger, den man von malloc(), calloc() oder realloc() erhalten hat).<br />
Achtung, wenn e<strong>in</strong> Zeiger übergeben wird, der nicht auf e<strong>in</strong>en von malloc() gelieferten Speicherblock<br />
zeigt, oder denselben Block zweimal freigibt wird <strong>die</strong> Speicherverwaltung korrupt, <strong>und</strong><br />
es muss mit Absturz oder verfälschten Daten gerechnet werden. (Um solche Probleme zu f<strong>in</strong>den<br />
gibt es spezielle Debug-Speicherverwaltungen, welche zusätzliche Überprüfungen vornehmen <strong>und</strong><br />
Fehlermeldungen ausgeben.)<br />
Wichtig, jeder Speicherblock, der angefordert wird, muss auch wieder freigegeben werden, sonst<br />
entsteht e<strong>in</strong> sogenanntes Speicherleck. Das heisst, dass der verfügbare Speicher ständig abnimmt,<br />
bis plötzlich ke<strong>in</strong> freier Speicher mehr übrig ist.<br />
Innerhalb von Interruptrout<strong>in</strong>en <strong>und</strong> zeitkritischen Codestücken sollten malloc() <strong>und</strong> free()<br />
nicht e<strong>in</strong>gesetzt werden. (Speicher vorher oder nachher allozieren resp. freigeben).<br />
Gedruckt am 11.09.2008 13:04:00 Letzte Änderung am: 11. September 2008 Version 2.4, I. Oesch 98/147