std::cout macht selbständig was im Hintergrund?



  • jup, und dann, statt eine kopie vom string in der map zu speichern, speicherst du dort einen zeiger auf eine lokale variable, die nach dem velassen der funktion mit müll überschrieben wird...
    (glaub ich)
    edit: zeig mal bitte die ganze funktion



  • ja ist

    map<char* str,int> m_cardMap;
    

    aber das ist doch egal?



  • Nein, du speicherst nur einen Zeiger auf eine char-Variable (genauer, da du einen String verwendest: Den Zeiger auf das erste Zeichen deines Strings) in der Map ab.

    Nun verliert der String auf den der Zeiger zeigt aber frühzeitig seine Gültigkeit. Ab dann zeigt dein Zeiger ins Leere. Schließlich hält die Map ja nur den Zeiger und keinen String, kopiert diesen folglich auch nicht.

    Im Falle von std::string hält sie den std::string und nicht den Zeiger auf einen C-String, es wird der gesamte std::string kopiert und du hast auch keine Probleme.

    MfG SideWinder



  • wobei, wenn es wirklich "const char*" und nicht "char*" ist, wenn du in der funktion wirklich nur solche zuweisungen:

    char nr[]="konstanter ausdruck"
    

    verwendest, sollte trotzdem alles okay sein... seltsam 🙄
    zeig mal die ganze funktion!



  • Solange er sich innerhalb der Funktion befindet ist alles wunderbar - egal ob const oder nicht. static würde etwas ändern, aber ich würde es immer noch als schlechten Stil ansehen.

    MfG SideWinder



  • char* getCString(){ return "dies ist ein konstanter string"; }
    

    naja... mit solchen dingern passiert ja eigentlich nie was schlimmes, gutes stil hin oder her...
    aber ich glaube dem OP nicht, dass er in der funktion nur konstante ausdrücke in die map speichert 😃



  • Keine Ahnung ob man davon ausgehen darf, dass Literale immer brav an der selben Stelle bleiben.

    MfG SideWinder



  • naja... einen funktionszeiger muss man ja auch nicht in jeder zeile vor der benutzung aktualisieren, weil die funktionen an sich im speicher nicht herumgeschoben werden. und die konstanten ausdrücke dadrin imho auch nicht.
    ⚠

    float* getPointerToConstantFloat(){ const float pi=3.1415926; return &pi; }
    

    ⚠
    aber ob sowas auch geht=keine ahnung. würde ich jetzt nicht riskieren... 😮

    edit: hab jetzt beides ausprobiert: das erste geht, das zweite definitiv nicht. Beim ersten gibts nicht mal warnungen vom compiler...



  • das ist jetzt voll seltsam, ich raff's nicht:

    char* getCString(){ return "abc"; } //das ist in ordnung
    cahr* getCString2(){ char c[4]="abc"; return c; } //da gibts krach
    

    kann mir bitte jemand erklären, inwiefern sich die beiden fälle unterscheiden? Für mich sieht der zweite fall ziemlich genauso aus, das entspricht 1:1 dem, was der OP in seiner funktion gemacht hat, und es klappt nicht! ⚠



  • char* getCString(){ return "abc"; } //das ist in ordnung
    

    ist gleich

    char* getCString(){ return adresseVomStringLiteralInDerExeDatei; } //das ist in ordnung
    

    und

    cahr* getCString2(){ char c[4]="abc"; return c; } //da gibts krach
    

    ist gleich

    cahr* getCString2(){ 
    char c[4]; //sowas wie STACKPOINTER=STACKPOINTER-4
    memcpy(c,adresseVomStringLiteralInDerExeDatei,5);
    return c; 
    } //da gibts krach
    


  • ich fasse nochmal zusammen:

    Downset schrieb:

    unsigned char nr[] = "asa";
    

    speichert zeiger auf lokale kopie.

    das cout scheint mir irgendwas zu machen weil wenn ich in einer anderen Funktion nach dem Schlüssel nr suche und dort das Ergebnis ausgebe kommt schrott raus

    jup. die lokale kopie ist inzwischen weg.



  • volkard schrieb:

    speichert zeiger auf lokale kopie.

    achso, okay! thx, da hab ich wieder mal was dazugelernt.. 🙂



  • Jo thx 👍

    MfG SideWinder



  • ok - weiter gehts

    wenn ich aber

    map<string, Tier>tiere;
    

    mache und Tiere so

    tiere.insert(std::make_pair("esel",new Tier("esel")));
    

    hinzufüge dann hab ich da ein Objekt aus einer Klasse erzeugt und hinzugefügt und das bleibt wie der string bestehen oder? weil ist ja kein pointer sondern neues objekt?



  • nur dass du "new" nicht brauchst. Es wird vom container auch so wunderbar kopiert

    (der pointer wird ja auch wunderbar kopiert, mit dem unterschied, dass er nach dem verlassen der funktion ins leere zeigt)

    wobei, wenn du das so machst, dann funktioniert es evtl. schneller, wenn der container sich mal reallokieren muss. Dann müssen nähmlich nicht die ganzen objekte, sondern nur die kurzen zeiger kopiert werden. Dann pass aber auf, dass du das am ende alles sauber mit "delete" aufräumst!



  • In dem Fall bleibts dir länger als lieb ist.

    map<string, Tier> tiere;
    //                      ok, wird std::string  
    tiere.insert(make_pair("esel",
    //                             kein new, einfach schaun das Tier copy-constructor hat
                                   Tier("esel"));
    

    Wenn du da ein new hinwirfst, wird dir das Objekt am Heap angelegt und bleibt länger im Speicher als dir lieb ist. Nämlich bis du es wieder explizit mit delete freigibst - nie.

    MfG SideWinder



  • SideWinder schrieb:

    nie

    häää??? wo ist denn das problem?? 😕 😮 😕 😮



  • Wenn er dort ein new platziert müsste er die Map vor ihrer Zerstörung durchiterieren und alle Elemente mit delete freigeben. Einen solchen Code konnte ihc nicht entdecken, folglich ist er mit new dabei ein großes Speicherleck zu erzeugen.

    MfG SideWinder



  • ach, so meinst du das... na gut, hier steht aber ausser der faulheit nichts im wege. 🤡



  • jo aber copy konstruktor brauch ich wenn ich eine kopie erzeugen will ich will das tier aber ganz neu anelegen und nicht kopieren?


Anmelden zum Antworten