Was ist hier falsch?



  • Hallo auch,

    kann mir jemand sagen, was hier falsch ist?

    Cstring str;
    char *buffer = new char[60];
    
    GetDlgItemText(MY_EDIT, str);
    buffer = str.GetBuffer();
    str.ReleaseBuffer();
    //... mach etwas mit 'buffer'
    
    delete[] buffer;
    

    Der Debugger spuckt in der Zeile 'delete[] buffer;' folgenden Fehler:
    "Unbehandelte Ausnahme bei ....."

    Hat jemand eine Idee?



  • Ich glaube es liegt am ReleaseBuffer bin mir aber nicht sicher.

    buffer ist ja ein _stinkordinärer_ Zeiger. Und den lässt du auf str.GetBuffer() zeigen. Und wenn du dann ReleaseBuffer machst, zeigt der ins Nirvana - aber da ist ja noch was vernünftiges - oh Wunder. Deswegen siehst du kein Problem.

    Naja und dann versuchst du auf einen freigegebenen Speicher noch ein delete zu machen und das geht schief.

    So! Das war meine Interpretation. Ich gebe zu, so superfit in der Materie bin ich nicht (mehr). 😞



  • buffer = str.GetBuffer();

    weist dem Pointer einen neuen Wert zu (und dein mit new allozierter geht verloren), kopiert nicht den Inhalt oder so.

    das delete versucht dann einen Speicherblock freizugeben der gar nicht direkt alloziert wurde (glück gehabt sonst würde es erst später knallen)

    Weiß ja nicht, was "macht was mit buffer" bedeutet, aber in den meisten fällen genügt

    CString str;
    GetDlgItemText(MY_EDIT, str); 
    TCHAR * buffer = str.GetBuffer(/* optional: Mindestlänge*/); 
    //... mach etwas mit 'buffer' 
    str.ReleaseBuffer();   // änderungen in "buffer" werden in CString übernommen
    

    (edit) fixed formatting



  • Danke für die schnelle Antwort. Eine weitere Frage hätte ich da dennoch:
    Wie 'kopiere' ich den Inhalt eines CString in eine Variable vom Typ char *, die mit new char[60] alokiert worden ist? Oder ist so etwas nicht möglich. Ich habe es auch mit strcpy versucht, aber auch hier gibt es eine Fehlermeldung bei delete[].



  • strcpy ist im prinzip richtig, du hattest aber bestimmt nocht das buffer = str.GetBuffer() drin, oder?

    andererseits ist es sehr empfehlenswert, _tcsncpy zu verwenden (Buffer Overrun + Unicode-Kompatibilität):

    CString str = ...
    
    int len = 60;
    TCHAR * buf = new TCHAR[len];
    _tcsncpy(buf, str, len);
    buf[len-1] = 0;   // terminating 0 in case of overflow
    


  • und ist es richtig, dass ich jetzt buf nicht mehr mit delete[] freigeben brauche?



  • q150022 schrieb:

    und ist es richtig, dass ich jetzt buf nicht mehr mit delete[] freigeben brauche?

    ...Probieren geht über Studieren - delete[] ist nötig

    Danke noch einmal!

    Darf ich weiter nerven?
    Folgender Code:

    void CMyClass::FuelleMitLeerzeichen(int anz, CString str, CString *pStr)
    {
        char *pLeerZeichen = new char[anz];
        CString EinString;
        TCHAR buf = new TCHAR[anz];
    
        for(int i = 0; i < anz; i++)
            *(pLeerZeichen + i) = ' ';
        *(pLeerZeichen + anz) = 0;
    
        EinString.Format("%s%s", str, pLeerZeichen);
        delete[] pLeerZeichen;
        _tcsncpy(buf, EinString, anz);
        buf[anz - 1] = 0;
        pStr->Format(_T("%s"), buf);
        delete[] buf;
    }
    

    Das Programm stürzt bei 'delete[] pLeerZeichen' ab. Wess jemand wie man das am geschicktesten löst/umgeht?



  • Wenn du auf *(pLeerZeichen + anz) zugreifen willst, musst du anz+1 chars reservieren.



  • MFK schrieb:

    Wenn du auf *(pLeerZeichen + anz) zugreifen willst, musst du anz+1 chars reservieren.

    Sowas logisches aber auch 😃
    Vielen Dank und schönes WE an alle



  • Sowas logisches aber auch

    Weil [0..anz-1] genau anz zeichen sind, und [0..anz] sind (anz+1) Zeichen


Log in to reply