CString wird nicht gelöscht oder was?



  • Hallo,
    Ich bin's mal wieder. 😃 (In letzter Zeit irgendwie sehr häufig)
    Ich bin an einem Programm in dem man unter anderen Profile anlegen und löschen können soll. Die Profile werden in Dateien gespeichert. Wenn nun ein Profil gelöscht werden soll rufe ich die

    void deleteProfile()
    

    Funktion auf.
    Diese löscht ein bereits geladenes Profil. Die Datei in dem das Profil gespeichert ist soll natürlich auch gelöscht werden. Dazu habe ich gelesen gibt es die Funktion

    remove()
    

    aus cstdio. cstdio nimmt wie man sich denken kann nur cStrings an. Mein Dateiname ist aber in einem

    std::string
    

    gespeichert. Das ist ja an sich kein Problem ... dachte ich. Meine Lösung war:

    #include <string>
    using namespace std;
    
    string user = "multipilz5";
    char* buffer = new char[user.length() + 5];
    strcpy_s(buffer, user.length() + 1, user.c_str());
    strcat_s(buffer, 5, ".txt");
    
    remove(buffer);
    
    delete[] buffer;
    

    Aber wenn ich das ausführe bekomme ich einen runtime error: L"String is not null terminated" && 0
    Bedeutet das etwa, dass mein cString nicht gelöscht wurde? Aber ich hab doch delete[] buffer; benutzt. 😕

    Ich weiß nicht was ich da falsch gemacht hab bzw. vergessen habe.

    @SeppJ du bist eh wieder der Erste der hilft 😉 (wahrscheinlich)

    Aber egal wer hilft, ich bin immer dankbar 😋 🙂



  • Bin zwar nicht SeppJ, aber was spricht gegen:

    remove((user + ".txt").c_str());
    

    (Wahrscheinlich solltest du besser eine Funktion haben, die dir zu einem User den Dateinamen holt!)

    Wenn du die strcpy/strcat nehmen willst, dann beachte, dass die Größe die Größe des Puffers ist. Und die _s -Versionen liefern auch einen Rückgabewert...



  • wie oben schon geschrieben ist remove() eine Funktion aus cstdio. in c gibt es keine std::strings. Deswegen will remove() einen cString. user ist jetzt aber ein std::string. also kann ich das so nicht in remove() verwenden.

    Die Funktion holt mir doch den Dateinamen her. Der setzt sich nämlich immer aus dem username und der Dateiendung zusammen. Das einzige Problem ist, (ich vermute zumindest dass es so ist) dass der Speicher nicht freigegeben wird. Weil da eben etwas von wegen string nicht null in der Errormeldung kommt.

    Was hat das eigentlich mit diesen Rückgabewerten bei den _s-Versionen auf sich. Da wird ein int zurückgegeben. Was fange ich damit an? Ich hab nur deswegen die _s-Versionen benutzt weil VisualStudio das so lieber mag.



  • multipilz5 schrieb:

    Aber wenn ich das ausführe bekomme ich einen runtime error: L"String is not null terminated" && 0
    Bedeutet das etwa, dass mein cString nicht gelöscht wurde? Aber ich hab doch delete[] buffer; benutzt. 😕

    Also Grundsätzlich folgendes:

    1. Wenn du einen Fehler hast der eine tolle Meldung gibt, kannst du den bei der Suchmaschine deines Vertrauens suchen. In deinem Fall ist das der "null terminated string". Den solltest du sogar kennen, das gehört zu den Grundlagen. Das ist im übrigen nicht böse gemeint von mir, aber zu vielen Themen gibt es sehr viele Beispiele die die Fehler sehr gut erläutern.

    2. Wenn du solche Crashes hast, nutze Haltepunkte und den Debug Modus dann bekommst du raus wo es geknallt hat. Das ist bei komplexeren Sachen dann auch ganz praktisch.

    3. Diese _s Funktionen sind sone Sache für sich. Ich mag sie nicht und hatte in der Vergangenheit einige sehr komische Fehler damit die ich nie gänzlich aufklären konnte.

    4. Da du schon std::string benutzt, dann bleib doch auch dabei, es macht keinen Sinn ungesichert Speicher zu holen und dann darin rumzukopieren statt einfach die Funktionalität der strings zu nutzen. wob hat es ja schon sehr schön gezeigt.

    EDIT:

    multipilz5 schrieb:

    wie oben schon geschrieben ist remove() eine Funktion aus cstdio. in c gibt es keine std::strings. Deswegen will remove() einen cString. user ist jetzt aber ein std::string. also kann ich das so nicht in remove() verwenden.

    Was denkst du denn was bei dieser Zeile "(user + ".txt").c_str()" genau entsteht wenn kein cstring?

    multipilz5 schrieb:

    Das einzige Problem ist, (ich vermute zumindest dass es so ist) dass der Speicher nicht freigegeben wird. Weil da eben etwas von wegen string nicht null in der Errormeldung kommt.

    Du vermutest nicht, du rätst, wenn du Haltepunkte genommen hättest wüsstest du das es bei deiner strcat_s Zeile knallt.

    multipilz5 schrieb:

    Was hat das eigentlich mit diesen Rückgabewerten bei den _s-Versionen auf sich. Da wird ein int zurückgegeben. Was fange ich damit an? Ich hab nur deswegen die _s-Versionen benutzt weil VisualStudio das so lieber mag.

    5s Google:
    http://en.cppreference.com/w/c/string/byte/strcat
    http://en.cppreference.com/w/c/string/byte/strcpy



  • Xebov schrieb:

    2. Wenn du solche Crashes hast, nutze Haltepunkte und den Debug Modus dann bekommst du raus wo es geknallt hat. Das ist bei komplexeren Sachen dann auch ganz praktisch.

    Jaaa ... das müsste ich mir mal anschauen wie das mit dem debuggen richtig funktioniert (schäm).

    Xebov schrieb:

    4. Da du schon std::string benutzt, dann bleib doch auch dabei, es macht keinen Sinn ungesichert Speicher zu holen und dann darin rumzukopieren statt einfach die Funktionalität der strings zu nutzen. wob hat es ja schon sehr schön gezeigt.

    Ja das geht tatsächlich sehr gut. (Danke an wob)

    Xebov schrieb:

    In deinem Fall ist das der "null terminated string". Den solltest du sogar kennen, das gehört zu den Grundlagen.

    Ich hatte bis jetzt das erste Mal überhaupt einen runtime error ... also bin ich diesem auch noch nie begegnet.

    Also es funktioniert jetzt auf jeden Fall, danke für die Hilfe 🙂



  • multipilz5 schrieb:

    Ich hatte bis jetzt das erste Mal überhaupt einen runtime error ... also bin ich diesem auch noch nie begegnet.

    Null terminated strings haben nichts mit runtime errors zu tun, es ist die Art und Weise wie strings funktionieren. Und wird eigentlich in jedem guten Tutorial erwähnt 😉



  • Xebov schrieb:

    Null terminated strings haben nichts mit runtime errors zu tun, es ist die Art und Weise wie strings funktionieren. Und wird eigentlich in jedem guten Tutorial erwähnt 😉

    Ach so. Ich hab das wahrscheinlich auch schon irgendwann mal gelesen aber schon wieder vergessen 😞



  • multipilz5 schrieb:

    Ich hab nur deswegen die _s-Versionen benutzt weil VisualStudio das so lieber mag.

    Du musst sie bloss richtig verwenden:
    https://msdn.microsoft.com/en-us/library/d45bbxx4.aspx

    char buf[16];
    strcpy_s(buf, 16, "Start");
    strcat_s(buf, 16, " End");               // Correct
    strcat_s(buf, 16 – strlen(buf), " End"); // Incorrect
    

Anmelden zum Antworten