Vollkommen irrer Fehler!



  • Hi Leude!

    Ich bin jetzt seit 1 1/2 tagen in meiner firma total am verzweifeln. 😞 😞

    ich hab ein mfc prog, dass im debug modus immer wieder abstürzt mit einem speicherzugriffsfehler. aber nur im debug modus. im release geht alles wunderbar.

    noch verrückter ist allerdings was im debug modus passiert. statt an der stelle, wo es abstürzt einen gelben pfeil darzustellen (wie bei einem normalem fehler), zeigt er ein grünes dreieck, mit der bemerkung, dass in der funktion, die er anzeigt, ein fehler passiert ist...
    Beispiel:

    if(dlg.DoModal() == IDOK) {...}
    

    und ich bin in der festen überzeugung, dass in DoModal() kein fehler existiert; ist schließlich von microsoft.

    wenn man dann sachen auskommentiert, wo man sich vorstellen könnte, dass sie fehler produzieren (dyn. speicherverwaltung, etc.), dann stürzt das programm anderswo ab.
    z.B. hier:

    if(init) {...}
    

    <-- er meint init wäre ungültig, obwohl init vorher per

    bool init;
    init=false; //an anderer stelle
    

    initialisiert wurde. den fehler zeigt er aber nur, wenn man anderes, dass nichts damit zu tun hat auskommentiert. sonst passiert nix!

    ich glaube der fehler dreht sich um folgende sache (auch, wenn der debugger anderen müll anzeigt):

    class Beispiel
    {
        CString strABC;
        bool init;
    
    }
    
    CArray<Beispiel*,Beispiel*> aArray;
    
    Beispiel* nArrayEl = new Beispiel();
    aArray.Add(nArrayEl);
    aArray[0].strABC = "Hallo"; // Alles i.O.
    aArray[0].strABC = "HalloHalloabc";
    

    Um so ähnliche Sachen, wie die letzte Zeile scheint das Programm sich immer wieder zu killen. kann es angehen, dass strABC den nachfolgenden Speicherbereich überschreibt??
    Oder, dass das Array nicht genug Speicher bereitsstellt?? <-- Aber das wäre doch eigentlich egal, weil ich nur ein pointer Array habe, oder???

    Bitte, Bitte, Bitte helft mir!!!!!!!!!!! habt ihr vielleicht eine Vorstellung woher diese komische Debugger Meldung kommen kann? Nicht im Detail sondern einfach allgemein???



  • habt ihr vielleicht eine Vorstellung woher diese komische Debugger Meldung kommen kann? Nicht im Detail sondern einfach allgemein???

    Im Prinzip ja - aber wie sag ich's meinen Chef 🙄

    Schätz' dich glücklich - Ich hab gestern zwei Stunden 'nen Absturz gesucht der nur im Release-Build bei voller Optimierung auftrat. Was 'ne elende Sauerei. 😡

    Die üblichen verdächtigen:

    1. Du schreibst über irgendeine Allokationsgrenze drüber raus (z.B. hinter dem endfe von einem Array)
    2. Du verwendest ein Objekt das schon freigegeben wurde
    3. Durch einen unsauberen cast, oder einen Header-Konflikt "verschiebt" sich ein this- bzw. Member-zeiger
    4. (selten) Du schreibst auf ein shared const Array/String

    Ein unsauberer Cast sieht z.B. so aus:

    class Z : public X
    {
    };
    
    void * p = (void *) pZ;
    pX = (X *) p;
    

    Der header-Konflikt tritt üblicherweise mit Lib's auf, kann aber im schlimsmten fall auch in einem Projekt passieren: man ändert ein struct (z.B. fügt noch einen Member ein), übersetzt ein CPP mit dem alten und ein CPP mit dem neuen Header (bzw. übersetzt die LIB nicht neu). Dann haben beide Module unterschiedliche Offsets zu Datenmembern oder abgeleiteten Klassen, und schreiben Daten an die falsche Stelle.

    1. und 2) haben die lustige Eigenschaft, daß da Problem zumeist viel später und an volkommen anderer Stelle auftritt als die Ursache liegt. 3) hat den neckischen Seiteneffekt, daß sich irgendwelche Daten "plötzlich" ändern, ohne das sie angefaßt werden (in wirklichkeit greift das programm auf verschiedene Adressen zu).

    "aArray[0].strABC" ist bestimmt "aArray[0]->strABC", und die zweite Zuweisung kann's nicht sein.

    Mehr kann ich leider nicht sagen...



  • Du verwendest ein Pointer-Array und benutzt . statt -> ?!?

    EnERgYzEr schrieb:

    CArray<Beispiel*,Beispiel*> aArray;
    
    Beispiel* nArrayEl = new Beispiel();
    aArray.Add(nArrayEl);
    aArray[0].strABC = "Hallo"; // Alles i.O.
    aArray[0].strABC = "HalloHalloabc";
    

    Mach da doch mal folgendes draus:

    aArray[0]->strABC = "Hallo"; // Alles i.O.
    aArray[0]->strABC = "HalloHalloabc";
    

    Wobei ich folgendes bevorzugen würde:

    aArray.GetAt(0)->strAbc = "HalloHalloabc";
    

    Ist mir schleierhaft, warum der Compiler das nicht anmeckert.



  • estartu_de schrieb:

    Mach da doch mal folgendes draus:

    aArray[0]->strABC = "Hallo"; // Alles i.O.
    aArray[0]->strABC = "HalloHalloabc";
    

    das ist nur ein tippfehler...

    in echt sieht das ganze ja ein bisschen anders aus und da verwende ich auch ->

    aber erst mal danke euch beiden!

    durch stundenlanges auskommentieren bin ich jetzt aber hinter einer anderen sache hinterher! (wenn ich die lösung hab, werd ich mich nochmal melden)



  • hi!!

    So ich hab das Problem jetzt weiter eingekreist und bin wo ganz anders gelandet:

    ich hab ein CTreeCtrl, dass mehrere Elemente enthält. Wenn man auf das Element doppelklickt oder auf einen Bearbeiten-Button drückt wird ein Dialog aufgerufen, der das entsprechende Element bearbeitet.

    Der oben beschriebene Fehler tritt nur auf, wenn man auf das element doppelklickt, dabei tut die funktion nichts anderes, als die button funktion aufzurufen:

    void CConChildDlg::OnNMDblclkTree1(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	OnBnClickedEdit();
    
    	*pResult = 0;
    }
    

    Nur, wenn man doppelklickt gibt es an folgender stelle in der funktion OnBnClickedEdit() einen fehler:

    CmySQLDlg dlg(...);
    if(dlg.DoModal()!=IDOK)
        return;
    

    dabei wird die funktion in beiden fällen doch einfach nur aufgerufen!!!! 😮
    😮 😮

    Der Fehler ist sonst identisch mit dem oben beschriebenen... Also der grüne Pfeil ohne konkrete Anhaltspunkte... bis auf:

    *HEAP[db COPY.exe]: HEAP: Free Heap block 166378 modified at 166394 after it was freed
    Unbehandelte Ausnahme bei 0x778a018c in db COPY.exe: Benutzerhaltepunkt.
    *

    😕 😮 😕 😮



  • Hallo !

    Bei komischen Fehlern hilft manchmal (im Menü):
    Erstellen -> Bereinigen
    Erstellen -> Alles neu erstellen.

    Tschüss



  • isabeau schrieb:

    Hallo !

    Bei komischen Fehlern hilft manchmal (im Menü):
    Erstellen -> Bereinigen
    Erstellen -> Alles neu erstellen.

    Tschüss

    das hab ich schon ein paar mal ausprobiert!

    <- hilft zwar häufig aber nicht in diesem fall



  • Wie sieht's denn aus?
    Hatte eine heftige Woche - deswegen die späte antwort.

    HEAP: Free Heap block 166378 modified at 166394 after it was freed
    Unbehandelte Ausnahme bei 0x778a018c in db COPY.exe: Benutzerhaltepunkt

    Du schreibst über eine Heap-Allokation drüber raus, wild auf dem Heap rum, oder benutzt einen schon delete'ten Zeiger.

    Weist darauf hin, das bereits eher was passiert. Ob und wann sich der Fehler bemerkbar macht, hängt halt davion ab, was in dem Moment grad in den Registern udn auf dem Stack steht - das kann das seltsame Verhalten (mal passiert's mal nicht) recht gut erklären.

    Die einfachste (aber teuerste) Lösung ist ein Tool wie BoundsChecker.
    (Tip: Für GlowCode gibt's eine Eval-version: http://www.glowcode.com Könnte dir schon weiterhelfen)

    Etwas mühseliger ist es, die CRT Memory Debug - Funktionen zu verwenden.

    Mit _CrtSetDbgFlag kann man noch einige heap Debug flags setzen: _CRTDBG_CHECK_ALWAYS_DF checkt den gesamten Heap bei jeder Allokation, das macht das programm zwar ewig langsam, aber man kommt näher an die Ursache ran.

    Eine andere Variante ist, an ausgewählten Stellen _CrtCheckMemory selbst aufzurufen, und so den Sündenbock "einzukreisen".

    Behalt aber immer im Hinterkopf, daß die Ursache immer noch ein Stückchen vor der Fehlermeldung liegen kann


Anmelden zum Antworten