Heap Probleme nach FreeLibrary
-
Hallo,
ich bin etwas verzweifelt, vielleicht kann mir hier ja ein Guru bei meinem Problem helfen.
Ich habe eine DLL und ein EXE. Die DLL legt am Heap Speicher an (mit new) den ich dann in der EXE wieder freigegeben will.
Das sollte theoretisch ja gehen wenn beide gegen die selbe CRT DLL linken (und das tun sie auch - in meinem Fall ist es msvcp80.dll). Das haut auch soweit alles hin (d.h. ich lege den Speicher in der DLL an und mache ein delete in der EXE).
ALLERDINGS ... wenn ich vor dem Freigeben ein FreeLibrary mache um die DLL zu entladen, dann funktioniert es nicht mehr und ich bekomme eine Exception bei dem delete.
Die Frage ist jetzt: warum? So wie ich das verstehe sollte das "unloaden" der DLL ja nichts am CRT Heap verändern, den sich DLL und EXE teilen. Auch in der Doku steht über derartige Effekte nichts ...
Im Web habe ich zu dem Problem nur gefunden, dass man wenn man den Heap zwischen DLL und EXE "sharen" will gegen die DLL-Version der CRT linken muss (was ich ja mache).
Also, vielleicht kann mir hier jemand helfen.
--
Vielen Dank,
Stefan
-
Hab keine Erklärung. Vermutlich gibt doch jemand in Deiner DLL den Speicher frei.
PS: Was geht denn genau nicht? Wie heisst die Fehlermeldung?
-
Jochen Kalmbach schrieb:
Hab keine Erklärung. Vermutlich gibt doch jemand in Deiner DLL den Speicher frei.
PS: Was geht denn genau nicht? Wie heisst die Fehlermeldung?Sieht nicht so aus auls würde der Speicher freigegeben: Ich hab' das ganze durchdebugged und der Destructor des angelegten Objekts wird nur ein einziges mal aufgerufen.
Ausserdem sollte es ja dann auch Probleme geben will ich die DLL nicht entlade. Das Ding hat keine spezielle DllMain, verwendet also nur die Standard _DllMainCRTStartup.
Der Fehler ist eine normale "du machst was mit einem ungültigen Pointer" Exception: "Access violation reading location 0x03da27ac."
--
Stefan
-
Stefan80 schrieb:
Ich habe eine DLL und ein EXE. Die DLL legt am Heap Speicher an (mit new) den ich dann in der EXE wieder freigegeben will.
auch wenn du's jetzt hinbekommen solltest, sowas kann später wieder zu problemen führen. mach's doch z.b. so
exe legt speicher an und gibt einen pointer an die dll
- oder -
dll holt sich speicher mit 'VirtualAlloc' welchen die exe mit 'VirtualFree' wieder freigeben kann.
-
net schrieb:
auch wenn du's jetzt hinbekommen solltest, sowas kann später wieder zu problemen führen. mach's doch z.b. so
exe legt speicher an und gibt einen pointer an die dll
- oder -
dll holt sich speicher mit 'VirtualAlloc' welchen die exe mit 'VirtualFree' wieder freigeben kann.Ist schon richtig was du sagst, aber wenn man eben mit einer ziemlich grossen Codebasis arbeiten muss ist es nicht so leicht das ganze Speichermanagement umzubauen ...
-
Stefan80 schrieb:
Ich habe eine DLL und ein EXE. Die DLL legt am Heap Speicher an (mit new) den ich dann in der EXE wieder freigegeben will.
Also dieses Design gehört verboten. Speicher in einer DLL zu allokieren und in einer EXE freizugeben geht nur wenn EXE und DLL die selbe als DLL gebundene CRT verwenden!
Ansonsten knallt es an allen Ecken, weil nicht der selbe Heap für die Allokationen verwendet wird.Verwenden EXE und CRT die selbe CRT als DLL? Oder hast Du die CRT etwa statisch gebunden?
-
Martin Richter schrieb:
Also dieses Design gehört verboten. Speicher in einer DLL zu allokieren und in einer EXE freizugeben geht nur wenn EXE und DLL die selbe als DLL gebundene CRT verwenden!
Ansonsten knallt es an allen Ecken, weil nicht der selbe Heap für die Allokationen verwendet wird.Verwenden EXE und CRT die selbe CRT als DLL? Oder hast Du die CRT etwa statisch gebunden?
Also wenn du mein ursprüngliches Posting gelesen hast, dann erkennst du, dass EXE und DLL dynamisch gegen die DLL-Version der CRT gelinkt werden, also beide eben schon den selben Heap (das hab ich auch überprüft) verwenden.
Im Übrigen habe ich jetzt eine Theorie was passieren könnte. Vielleicht hat hier jemand Erfahrungen damit:
Bei dem Speicher der DLL angelegt und in der EXE freigegeben werden soll handelt es sich um die Instanz eine Klasse. Der Code dieser Klasse liegt in einer Library gegen die sowohl EXE als auch DLL statisch linken. Könnte es sein, dass durch das Entladen der DLL mit FreeLibrary auch der Code der Klasse entladen wird obwohl die LIB auch gegen die EXE gelinkt wird?
-
Stefan80 schrieb:
Bei dem Speicher der DLL angelegt und in der EXE freigegeben werden soll handelt es sich um die Instanz eine Klasse. Der Code dieser Klasse liegt in einer Library gegen die sowohl EXE als auch DLL statisch linken. Könnte es sein, dass durch das Entladen der DLL mit FreeLibrary auch der Code der Klasse entladen wird obwohl die LIB auch gegen die EXE gelinkt wird?
Ja, das ist sogar sehr wahrscheinlich - FreeLibrary() räumt alles auf, was zur Lib gehört, also auch den Code der darin enthaltenen Funktionen (inklusive deinem Dtor).
-
Stefan80 schrieb:
Bei dem Speicher der DLL angelegt und in der EXE freigegeben werden soll handelt es sich um die Instanz eine Klasse. Der Code dieser Klasse liegt in einer Library gegen die sowohl EXE als auch DLL statisch linken. Könnte es sein, dass durch das Entladen der DLL mit FreeLibrary auch der Code der Klasse entladen wird obwohl die LIB auch gegen die EXE gelinkt wird?
das stimmt schon. wenn beide, also die dll und die exe, eine lib statisch linken dann hat jeder seine eigene kopie der lib. der code ist also doppelt vorhanden und wenn du die dll entdlädst ist deren code nicht mehr da....
-
net schrieb:
das stimmt schon. wenn beide, also die dll und die exe, eine lib statisch linken dann hat jeder seine eigene kopie der lib. der code ist also doppelt vorhanden und wenn du die dll entdlädst ist deren code nicht mehr da....
Hmmmm, ja ... das macht schon Sinn. Die Frage ist nur wie ich das lösen könnte.
Kurze Erklärung: Wir haben eine recht grosse Library die immer statisch gegen die EXE gelinkt wird. Die DLL von der ich spreche ist Teil eines Plugin-Mechanismus in der Library, d.h. die Lib lädt eine DLL, die DLL legt ein paar Objekte an und wird dann wieder entladen (wie gesagt handelt es sich dabei immer um "bekannte" Objekte aus die Library).
Irgendwelche Ideen wie ich das hinkriegen könnte ohne substantielle Änderungen an unserer Library vorzunehmen ... ?
Danke für eure Hilfe!
--
Schöne Grüsse,
Stefan
-
Stefan80 schrieb:
Irgendwelche Ideen wie ich das hinkriegen könnte ohne substantielle Änderungen an unserer Library vorzunehmen ... ?
warum musst du die dll entladen? lass die doch einfach da
-
net schrieb:
Irgendwelche Ideen wie ich das hinkriegen könnte ohne substantielle Änderungen an unserer Library vorzunehmen ... ?
warum musst du die dll entladen? lass die doch einfach da[/quote]
Naja, es wird dann relativ viele solcher Plugin-DLLs geben (> 50), die jeweils nur für eine kurze Zeit benötigt werden. Ich weiss nicht ob es optimal ist sie einfach nicht zu entladen ...