 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Eternal_pain

Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 10.11.2011, 21:52 Titel: Speicherverwaltung (deallocate/imagedestroy) |
|
|
mir war vor kurzem aufgefallen als ich ein mit Imagecreate erstellten Buffer (versehentlich) mit Deallocate freigegeben habe bzw freigeben wollte, das mein Programm sich nach einiger Zeit aufhängt und im Taskmanager konnte ich beobachten wie der Speicherverbrauch stetig stieg...
Eigentlich war ich der Meinung das es im grunde keinen unterschied macht so wie auch ein Imagebuffer mit (C)Allocate erstellt, mit Imagedestroy wieder freizugeben keinen Fehler zurück gibt...
Meiner Meinung nach war das in früheren Versionen vom FBC nicht der Fall,
was also ist der Unterschied beim erstellen bzw freigeben der beiden möglichkeiten (abgesehen von 'headerinformationen') und wie kommt es das der Speicher wenn unterschiedlich erstellt/freigegeben nicht wirklich wieder freigegeben wird?! _________________
 |
|
Nach oben |
|
 |
MOD Fleißiger Referenzredakteur

Anmeldungsdatum: 10.09.2007 Beiträge: 1003
|
Verfasst am: 10.11.2011, 22:38 Titel: |
|
|
Generell sollte man natürlich so dealloziieren, wie man alloziiert hat, egal was im Hintergrund ist. Tatsache ist aber, dass ImageCreate mehr als nur ein Allocate durchführt und deswegen auch ImageDestroy anders funktioniert als Deallocate. Das hat vor allem den Grund, dass in der fbgfx ein interessanter Hack ausgeführt wird.
Wer es sich direkt ansehen will, der schaut in die libfb_gfx_image.c um Zeile 72 und 111. Ansonsten hier ein Funktionsbeispiel:
http://www.devmaster.net/forums/showpost.php?p=40757&postcount=7
Dabei wird die Startadresse des Bilds ist dabei ein Vielfaches von 16, wodurch die tatsächliche Adresse direkt VOR dem Pointer liegt. Mit dem Index '-1' wird also dann der richtige Punkt angegeben und dann auch freigegeben. Etwas kompliziert, ich hab es mir gerade auch noch von Jojo erklären lassen, da ich so ein Konstrukt selbst noch nicht gesehen habe. Falls was falsch ist oder Ergänzungen nötig wären, kann Jojo ja gern nochmal weiter erklären. |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 10.11.2011, 22:49 Titel: |
|
|
Richtig.
Als Beispiel zur Verdeutlichung, warum ImageCreate nur zusammen mit ImageDestroy funktioniert:
Angenommen, der malloc-Aufruf in ImageCreate liefert die Adresse 23 zurück.
Die Startadresse der Bilddaten wird auf Adresse (23 + 15) & ~15 gesetzt = 32.
Das ist effizienter zu cachen und damit zu lesen / schreiben, da damit die Wahrscheinlichkeit hoch liegt, dass die Bilddaten auf der Grenze einer Cache Line (typischerweise 64, 128, ... Byte breit) liegen.
Um den Speicherblock freizugeben, genügt es nicht, nur die gepaddete Adresse zu kennen. Man muss den ursprünglichen Start des allozierten Blocks (das war 23) kennen.
Deshalb wird an Adresse 32 - sizeof(void *) = 28 (auf einer 32-Bit-Architektur) diese ursprüngliche Adresse abgelegt.
ImageDestroy liest dann von dieser Stelle die ursprüngliche Adresse und free-t diese dann. Ein normalles Deallocate würde versuchen, den Speicher an Adresse freizugeben, aber es wurde vorher kein Speicherblock alloziert, der an dieser Adresse beginnt. Wenn das nicht zu Problemen führt, ist das purer zufall!
Beispiel mit den Variablennamen aus der libfb_gfx_image.c:
Code: |
+-23-+-24-+-25-+-26-+-27-+-28-+-29-+-30-+-31-+-32-+-33-+-34-+-35-+-36-+-37-+-38-+-39-+-40-+
| tmp| | | | | (void **)image[-1]| image image image image image image image...
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+ |
_________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|