Speicherproblem bei Bibliotheken



  • Hallo!

    Ich habe eine Bibliothek geschrieben (unter Windows als DLL, aber das Problem ist bei Shared Libraries unter anderen Systemen vermutlich das gleiche). Diese enthält eine Funktion:

    IrgendeineKlasse irgendeine_funktion(){
      return IrgendeineKlasse();
    }
    

    "IrgendeineKlasse" ist eine selbst geschriebene Klasse, die im Konstruktor Speicher allokiert und im Destruktor wieder freigibt. Obiger Code erzeugt also eine neue Instanz dieser Klasse und gibt sie nach außen zurück (also aus der Bibliothek hinaus). Das Problem ist: sobald draußen der Destruktor dieser Klasse versucht den Speicher freizugeben, stürzt das Programm ab. Ich glaube es liegt daran dass der Speicher in einem anderen Prozess angelegt wurde als er freigegeben werden soll.

    Umgekehrt geht es allerdings:

    void irgendeine_funktion(IrgendeineKlasse a){
    }
    

    Ruft man diese Funktion mit:

    irgendeine_funktion(IrgendeineKlasse());
    

    auf, so muss am Ende der aufgerufenen Funktion das als Parameter übergebene Objekt über den Destruktor zerstört werden. Das funktioniert problemlos.

    Wie ist das zu erklären? Werden etwa beim Aufruf einer Bibliotheksfunktion die Parameter bereits im Kontext der Bibliothek erstellt?

    Danke im Voraus!

    mfg



  • Hat deine übergebene Klasse auch einen ordentlichen Copy-Ctor und op=, der den verwalteten Speicher tatsächlich kopiert?

    (und btw, funktioniert der Code, wenn du die selbe Funktion "intern" aufrufst?)



  • Wenn ich die Funktion intern aufrufe geht es.

    Copy-Constructor und =-Operator sind vorhangen, werden aber eigentlich gar nicht benötigt.

    Wenn man diesen Code ausführt:

    MyClass c;
    return c;
    

    , dann wird zuerst eine Instanz erstellt und diese dann für das Zurückgeben mit dem Copy-Constructor kopiert.

    Bei

    return MyClass();
    

    (so wie ich es gemacht habe) wird aber direkt das gerade erstellte Objekt zurückgegeben. Beim Aufruf einer Funktion funktioniert es analog.

    mfg



  • ChrisR schrieb:

    Ich glaube es liegt daran dass der Speicher in einem anderen Prozess angelegt wurde als er freigegeben werden soll.

    ich schätze mal auf devstudio 😉
    in dem fall bei den properties zu der lib _und_ zu dem programm jeweils multithreaded DLL eintragen und rebuild.



  • auf gar keinen fall darfst du den rückgabewert von

    IrgendeineKlasse irgendeine_funktion(){
      return IrgendeineKlasse(); 
    }
    

    mit delete wieder freigeben! delete darf nur auf von new gelieferte zeiger angewendet werden. der ausdruck "IrgendeineKlasse()" erzeugt ein temoräres objekt, daß, nachdem es von return in das rückgaberegister kopiert worden ist, automatisch wieder zerstört wird.

    das selbe gilt auch für

    irgendeine_funktion(IrgendeineKlasse());
    

    das argument ist ein temoräres objekt, das nach beendigung des funktionsaufrufs automatisch zerstört wird. auch hier darf das argument auf keinen fall in der funktion mit delete freigegeben werden.

    wie hast du den compiler überhaupt dazu überredet, delete auf etwas anderes als einen zeiger anzuwenden 😕 normalerweise sollte da eine fehlermeldung kommen.


Anmelden zum Antworten