Hallo Olaf,
Das ist das selbe Problem wie mit Zeigern in C.
Genial, wenn man damit umgehen kann und frustrierend wenn man das Konzept nicht verstanden hat und nicht aufpasst!
Es gibt drei grundlegende Gefahren:
1. Wenn man mit malloc() zu wenig Platz für ein Objekt anfordert überschreibt man natürlich irgendein anderes Objekt. Wie sich die Software verhält hängt jetzt davon ab, welches Objekt sich gerade hinter diesem Objekt befindet. Wenn der Speicher unbenutzt ist, passiert im besten Fall scheinbar gar nichts. Da die Speicherverwaltung dynamisch ist, wird auch das Verhalten der Software entsprechend unvorhersehbar. Möglich ist auch, dass man den Heap killt, in den ersten Bytes eines Verwaltungsblocks befinden sich Verwaltungsinformationen.
2. Wenn man den Block mit free() zurückgegeben hat, kann man natürlich weiterhin mit dem Zeiger auf diesen Speicherbereich zugreifen. Auch jetzt ist das Verhalten nicht vorhersehbar. Je nachdem ob der Block schon weiter verwendet wird oder nicht. Aus Laufzeitgründen wird der Block mit free() auch nicht auf 0 gesetzt, die Daten des Objekts stehen also noch im Speicher.
Hier hilft es wenn man, zumindest bei der Debug-Version folgendermassen vorgeht:
Allerdings muss man auch alle Kopien von ptr zurücksetzen, wobei es schon grundsätzlich schlechter Programmierstil ist, hier mit mehreren Variablen zu arbeiten ....Code:free(ptr); ptr = NULL;
3. Vergisst man abgelaufenen Objekte mit free() an den Heap zurückzugeben geht einem mit der Zeit der Speicher aus.
Den externen Speicher musst du dann für die maximale Objektgrösse und die maximale Anzahl an Objekten auslegen!
Wenn die typischen Objekte z.B. 16 Byte gross sind und das Grösste 4KB, versaust du jede Menge Speicher
Für 10 Objekte brauchst du dann rund 40KB Speicher. Da könnte man aber problemlos über 2'500 16-Bit Objekte unterbringen.
Jede Menge, habe auch schon selber malloc() und Co selber implementiert, allerdings auf Renesas-CPUs (H8-Familie)
Im einfachsten Fall hat jedes Heap-Element einen Header mit einem Zeiger auf das nächste Element und einem Flag welches angibt ob der Block frei oder belegt ist.
Da die H8 16-Bit Zugriffe nur auf gerade Adressen machen können, belegt die Standardvariante, beim 16-Bit Speichermodell, für den Header 4 Bytes. 2Bytes für den Zeiger. 1 Bit für das Flag und 15 Bit sind verschwendet Ich habe dann das Flag in das letzte Adressbit gepackt, die H8 setzen das letzte Bit bei einem Speicherzugriff einfach per Hardware auf 0. Bei kleinen Objekten und nur ein paar KB RAM macht das einiges aus.
MfG Peter(TOO)
Lesezeichen