Befreien von Spiecher schlägt fehl



  • Nein trotzdem der selbe Fehler.



  • Trotzdem musst du immer die richtige Variante benutzen (delete und delete[] sind ein Unterschied, siehe MSDN).

    Warum verwendest du eigentlich abwechselnd new und malloc? Kann man zwar machen, aber du könntest deinen malloc-Aufruf genausogut durch new ersetzen und somit einheitlich bleiben...



  • CrazyPlaya schrieb:

    LPOLESTR lpMicGuid = new WCHAR[39];
    lpMicGuid = A2OLE(pVal);
    

    Und hier ist der mit new geholte Speicher schon nicht mehr erreichbar, weil der Zeiger nun auf den Rückgabewert von A2OLE zeigt.



  • Eieieiei....

    // LPOLESTR lpMicGuid = new WCHAR[39];
    // lpMicGuid = A2OLE(pVal); // falsch, überschreibt den Zeiger "lpMicGuid", der somit nichtmehr auf den neu angeforderten Bereich zeigt,
                                // sondern auf einen Temporären Bereich der vom Makro A2OLE irgendwie herbeigezabuert wird
    // besser & einfacher:
    std::wstring micGuidString = A2OLE(pVal);
    
    // wieso so kompliziert?
    // GUID guid;
    // CLSIDFromString(lpMicGuid, &guid);
    // m_lpGuidMic = (LPGUID)malloc(sizeof(GUID)); // wieso malloc?
    // memcpy(m_lpGuidMic, &guid, sizeof(guid));
    m_lpGuidMic = new GUID; // muss dann natürlich auch mit delete wieder freigegeben werden
    CLSIDFromString(micGuidString.c_str(), m_lpGuidMic);
    
    // fertig.
    
    // brauchen wir jetzt nimmer, std::wstring räumt sich selbst auf
    // if(lpMicGuid != NULL)
    // {
    //      delete lpMicGuid;
    //      lpMicGuid = NULL;
    // }
    

    Und... wieso muss m_lpGuidMic überhaupt ein Zeiger sein? Ein einfaches Nicht-Zeiger-Member ("GUID m_micGuid;") würde reichen. Oder ggf. ein boost::scoped_ptr<GUID> oder std::auto_ptr<GUID>.



  • @MFK: Stimmt, dann brauch ich den ja gar nicht mehr mit new initialisieren.

    @_matze: Hast du schon recht. Die Abwechslung zwischen new und malloc kommt vom Copy and Paste:D:D.
    lalala 😃



  • Dann hab ich gleich noch eine Frage zur Speicherverwaltung.

    ich habe eine Thread, dem ich über eine Struktur einen Zeiger auf eine Klasse übergebe.
    Z.B. so

    MyClass myClass = new MyClass();
    TPARAM tParam;
    tParam.CMyClass = myClass;
    hThread = CreateThread(NULL, 0, &MyThread, &tParam, 0, &dwThreadId);
    

    Und hier der Thread
    DWORD WINAPI CMyClass::MyThread(PVOID pParam)
    {
    TPARAM* tParam = (TPARAM*)pParam;
    CMyClass* myClass = pParam->myClass;
    }

    Wie bereinige ich hier am Ende am besten meinen Speicher?



  • Kannst du die Instanz deiner Klasse nicht direkt im Thread erzeugen (und da wieder freigeben)? Du erzeugst ja sowieso erst kurz vorher eine neue Instanz. Oder wird die später noch gebraucht? Dann sollte das Freigeben vermutlich nix mi dem Thread zu tun haben...



  • Ich benötige die Instanz der Klasse bereits vor dem Threadaufruf.



  • delete myClass;
    

    oder

    delete pParam->myClass;
    


  • Dann kann ich aber nach Abarbeitung des Threads nicht mehr mit der Instanz der Klasse weiterarbeiten.



  • CrazyPlaya schrieb:

    Dann kann ich aber nach Abarbeitung des Threads nicht mehr mit der Instanz der Klasse weiterarbeiten.

    Du hattest auch nicht erwähnt, dass du das musst.
    Stell doch erst mal die Anforderungen auf, anstatt die Helfer vor die Wand laufen zu lassen.



  • Ja, dann war dein Beispiel falsch. Da hast du nämlich eine frisch erzeugte Instanz and den Thread übergeben. So aber hat doch das Freigeben gar nix mit dem Thread zu tun. Dort ist die Instanz nur ein durchlaufender Posten.



  • @MFK: Sorry, mein Fehler. Hats recht hätte ich erwähnen müssen.

    @_matze: Das hab ich auch gedacht, aber irgendwo bleibt noch ein Speicherleck, in dem der Inhalt ist, welcher in dem Thread generiert wird.
    Daher habe ich angenommen dass innerhalb des Threads noch etwas nicht korrekt freigegeben wird.



  • Du solltest einfach genau ein new und ein delete aufrufen. Dann sollte nix schiefgehen. Was macht denn der Thread? Weist du da noch mal Speicher zu oder machst sonstige krumme Sachen?



  • Ja so mach ich es ja bereits. Bevor ich den Thread aufrufe wird die Klasse instanziiert und dann bearbeitet. Dann Thread abarbeiten, hier wird kein neuer Speicher zugewiesen. Dann wird weiter mit der Instanz gearbeiten und beim Beenden wird ein delete ausgeführt.



  • Hast du das mal mit Breakpoints überprüft? Passiert das auch, wenn du sämtliche Bearbeitungen auskommentierst (also nur new+delete)?


Anmelden zum Antworten