(char* benutzen == mem leak) == wahr_oder_falsch



  • Guten Abend.

    Ich benötige Aufklärung! 🤡

    class charSpeicher
    {
         char* text;
    
    public:
         charSpeicher() : text(0) {}
    
         const char* getChar() { return text; } //FEHLER VERMUTET
         void        setChar(const char* c) 
         {
                if( text ) delete text;
                strcpy(text, c);
         }
    }
    
    void irgendwo()
    {
        charSpeicher cs;
    
        std::string irgendwas("Blablabla");
        const char* c = "BLABLABLA!";
    
        cs.setChar(irgendwas.c_str());
        cs.setChar(c);
    }
    

    Ist da irgendwo ein Speicherleck oder sowas in der Art?? Ich arbeite bis jetzt immer nur mit std::string und möchte mich endlich mal mit chars "auskennen" 😉

    Zwar kein Konkretes Problem aber ihr findet mögliche Fehler sicher schnell 🕶

    Dankesehr



  • Oder sollte man auch std::string immer und überall verwenden? 😕



  • void        setChar(const char* c) 
         {
                if( text ) delete[] text;//die [] neu
                text = new char[strlen(c)+1];//neu
                strcpy(text, c);
         }
    


  • rubber schrieb:

    Oder sollte man auch std::string immer und überall verwenden? 😕

    nicht immer und überall. aber hier sicherlich und meistens sonst auch.



  • rubber schrieb:

    Ist da irgendwo ein Speicherleck oder sowas in der Art?? Ich arbeite bis jetzt immer nur mit std::string und möchte mich endlich mal mit chars "auskennen" 😉

    Normalerweise sollte man mit C anfangen und daher erst die char 's kennenlernen. 😃

    rubber schrieb:

    Zwar kein Konkretes Problem aber ihr findet mögliche Fehler sicher schnell 🕶

    Bei setChar kopierst du den übergebenen Speicher in die Member-Variable text, für die du aber noch keinen Speicher angefordert hast. Was du vermutlich eher vorhattest: Setz die Variable selbst auf den übergebenen Parameter. Damit brauchst du auch nicht kopieren, die Variable zeigt einfach auf den Speicher, der bei setChar übergeben wurde. Dann brauchst du auch nicht delete aufrufen, der Speicher wird automatisch freigegeben, wenn die Variable aus dem Scope verschwindet (in diesem Fall beim Verlassen der main -Funktion). Aber Achtung: dann kannst Du sie auch nicht mehr in deiner Klasser verwenden.

    Kleiner Hinweis: mehrere char 's werden im allgemeinen (auch in C) als Strings bezeichnet. 🙂



  • Hehe ok, danke. Habs verstanden soweit 🤡
    (Nein, ich habe nie C programmiert 🙄 )

    Ich habe gehört dass std::string deutlich langsamer ist und man immerzu versuchen sollte std::string zu nutzen... wohl nicht wahr?



  • rubber schrieb:

    Hehe ok, danke. Habs verstanden soweit 🤡
    (Nein, ich habe nie C programmiert 🙄 )

    Ich habe gehört dass std::string deutlich langsamer ist und man immerzu versuchen sollte std::string zu nutzen... wohl nicht wahr?

    Ich meine natürlich "(...) versuchen sollte char* zu nutzen (...)"



  • Natürlich ist es langsamer, aber das spielt bei heutigen Prozessoren nahezu keine eine Rolle mehr. Im Gegenzug zur "Performance-Einbuße" kannst du den String allerdings bequem verwalten und beliebig "verlängern" (und noch viele andere schöne Dinge damit tun).
    In C++ solltest du char* nur noch einsetzen, wenn es performance-mäßig wirklich kritisch wird oder du manuelle Speicherverwaltung brauchst.



  • rubber schrieb:

    Ich habe gehört dass std::string deutlich langsamer ist und man immerzu versuchen sollte char* zu nutzen... wohl nicht wahr?

    Nein, das ist nicht wahr. std::string ist für viele Fälle sehr gut geeignet, weil er die Speicherverwaltung übernimmt. Allerdings benötigst du vielleicht nicht immer autonome Container. Zum Beispiel, wenn du nur ein Zeichenkettenliteral als const char* durchreichst. Aber sobald du manuell mit new[] und delete[] beginnst zu arbeiten und dein Anwendungs-Code zu Low-Level-Gefrickel verkommt, wäre std::string (oder je nachdem ein anderer, z.B. eigener String-Container) die bessere Wahl.



  • devkid schrieb:

    Natürlich ist es langsamer, aber das spielt bei heutigen Prozessoren nahezu keine eine Rolle mehr. Im Gegenzug zur "Performance-Einbuße" kannst du den String allerdings bequem verwalten und beliebig "verlängern" (und noch viele andere schöne Dinge damit tun).
    In C++ solltest du char* nur noch einsetzen, wenn es performance-mäßig wirklich kritisch wird oder du manuelle Speicherverwaltung brauchst.

    Damit sind wohl all meine char Fragen befriedigt.
    Ich danke euch! 😃



  • rubber schrieb:

    Ich habe gehört dass std::string deutlich langsamer ist und man immerzu versuchen sollte char* zu nutzen... wohl nicht wahr?

    das ist nicht wahr.
    was du da gemacht hast, war eine klasse um char* zu schreiben, und nix anderes ist std::string ja auch.
    allerdings haben die macher von std::string schon etliche ausgefuchste tricks auf lager, an die ein anfänger in den erstan paar jahren nicht heranreicht.

    allerdinsg eine sache gibts:
    wenn man einen char* hat und einen char* braucht, ist es unfug, zwischendurch einen std::string zu bauen.
    siehe

    void deleteFile(string filename)
    {
       RemoveFileOderWasVomBetriebssystem(filename.c_str());
    }
    ...
    int main(){
       deleteFile("c:\\autoexec.bat");
    }
    

    hier ist es einfach krank, den dateinamen erstmal in einen string zu wandeln, um dann den char* wieder rauszuziehen.



  • @Nexus: Hihi, sag sowas nie in der Nähe von einem C-ler *gg*

    Gut zu wissen wie es geht. Dann bleibe ich wohl beim std::string 🙂



  • devkid schrieb:

    Natürlich ist es langsamer, aber das spielt bei heutigen Prozessoren nahezu keine eine Rolle mehr.

    50 prozent sind 50 prozent. der schnellere prozessor ändert daran nichts.



  • rubber schrieb:

    @Nexus: Hihi, sag sowas nie in der Nähe von einem C-ler *gg*

    In C ist das eben die einzige Möglichkeit und entsprechend muss man schauen, dass man damit zurecht kommt. Wenn man jedoch schon C++ programmiert, sollte man auch die Vorzüge von Objektorientierung, RAII und generischer Programmierung nutzen. 😉

    volkard schrieb:

    50 prozent sind 50 prozent. der schnellere prozessor ändert daran nichts.

    Was für 50%?

    Falls std::string wegen gewisser Aspekte immer noch viel langsamer als rohe char -Arrays sein sollte, ist es mit einer eigenen Klasse meist möglich, nahezu an die Originalgeschwindigkeit heranzukommen. Zumal Dinge wie malloc() von C in C++ nicht langsamer sind, wenn sie in einer Klassen-Memberfunktion stehen. Ein wenig Optimierungen gehören natürlich auch dazu.



  • Nexus schrieb:

    volkard schrieb:

    50 prozent sind 50 prozent. der schnellere prozessor ändert daran nichts.

    Was für 50%?

    das war die antwort auf

    Natürlich ist es langsamer, aber das spielt bei heutigen Prozessoren nahezu keine eine Rolle mehr.

    wenn etwas auf einem alten prozessor halb so schnell war, ist es auf dem neuen auch halb so schnell.
    diese argument mit dem neuen prozessor war schrott. deswegen hab ich widersprochen. das hat nix damit zu tun, ob std::string schneller oder langsamer als rohe char* ist.



  • Normalerweise sollte man mit C anfangen und daher erst die char's kennenlernen.

    Das ist absoluter quatsch.
    Simon



  • volkard schrieb:

    diese argument mit dem neuen prozessor war schrott. deswegen hab ich widersprochen. das hat nix damit zu tun, ob std::string schneller oder langsamer als rohe char* ist.

    naja, aber wenn damals (wann auch immer das war), das kopieren eines C-Strings meinetwegen 100ms und eines C++-Strings dementsprechend 150ms gedauert hat und es heute nur noch 10 respektive 15ms dauert kann man wohl durchaus behaupten, dass es heute kaum noch einen Unterschied macht (5ms sind vll noch vernachlässigbar, was bei 50ms schonmal eng werden kann)



  • devkid schrieb:

    ...Normalerweise sollte man mit C anfangen und daher erst die char 's kennenlernen. ...mehrere char 's werden im allgemeinen (auch in C) als Strings bezeichnet. 🙂

    devkid schrieb:

    Natürlich ist es langsamer, ...
    In C++ solltest du char* nur noch einsetzen, wenn es performance-mäßig wirklich kritisch wird oder du manuelle Speicherverwaltung brauchst.

    Sorry, aber da ist soviel Zeug dabei, das ich falsch finde, dass ich da mal widersprechen muss:
    - Der Weg "von C zu C++" und "von char* zu std::string" ist schon lange weder Standard noch hilfreich. Man kann problemlos (einige meinen sogar "besser") direkt mit C++ und std::string einsteigen.
    - Gerade im C++-Forum ist es sehr hilfreich, die Terminologie zu trennen ...
    - Natürlich sind std::string nicht "natürlich langsamer". Werden dieselben Aufgaben erledigt, sind beide auch gleich "schnell". Das Problem ist, dass oftmals ein einzelner strcpy()-Call mit einem std::string::append() verglichen wird ... letzterer macht aber einfach viel mehr.
    - Für den Vorzug von char* ggü. std::string spielen sehr viel mehr (und üblicherweise wichtigere) Kriterien die ausschlaggebende Rolle. Vorgegebene APIs, exception-safety, ...

    Alles keine wirklichen "Neckbreaker", aber in der Summe doch so viel, dass ich einfach mal gegenhalten musste. 😉

    Gruß,

    Simon2.



  • zwutz schrieb:

    naja, aber wenn damals (wann auch immer das war), das kopieren eines C-Strings meinetwegen 100ms und eines C++-Strings dementsprechend 150ms gedauert hat und es heute nur noch 10 respektive 15ms dauert kann man wohl durchaus behaupten, dass es heute kaum noch einen Unterschied macht (5ms sind vll noch vernachlässigbar, was bei 50ms schonmal eng werden kann)

    Nicht, wenn man heute 10mal soviele Strings kopiert wie "damals".


Log in to reply