06.10.2013 Aufrufe

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

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!