Problem mit malloc und new



  • sizeof char == 1 schrieb:

    Was daran lesbarer sein soll...?!

    Für mich ist es nun mal lesbarer, find' dich damit ab. Jedes mal, wenn jemand

    int * Pointer = new int [10];
    

    schreibt, möchte ich gleichzeitig heulen und den Programmierer strangulieren.

    BOBString::BOBString(const char *str) {
        // FIXME: str auf NULL überprüfen, sonst kracht es.
        this->str = new char[this->len = std::stlren(str) + 1];
        std::strcpy(this->str, str);
    }
    

    Das einzige, was mir (schon vorher, und zwar Sekunden vor deinem Post) aufgefallen ist, ist dass ich wohl malloc und new ein bisschen durcheinandergebracht habe (sizeof, was habe ich mir dabei gedacht ... :().

    Zeiger auf NULL prüfen ist nicht nötig, bei new wird einfach eine std::bad_alloc -Exception geworfen. Mann, das habe ich mal voll ausgenutzt ... im catch -Block ein goto auf hinter try , und ich hatte blitzschnell 2 Gigabyte reservierten Speicher ... 😃



  • Und selbst, wenn sizeof(char)!=1 wäre, dann wäre

    str=new char[this->len+sizeof(char)];
    

    erst recht töricht, weil in [] die Anzahl steht und nicht die Größe in Bytes.

    Aber mir scheint, Du wolltest damit rohen Speicher besorgen.
    Das macht man wiederum mit

    str=::operator new(len+1);
    

    Und wenn man schon strlen benutzt, darf's auch ein bißchen memcpy sein.

    Lesbarer fände ich die Schleife mit str[i]!='\0'.

    Die Schleife ist seltsam. Sie soll auf jeden Fall mindestens einen char kopieren? Der FI/AE würde das eine fußgesteuerte Schleife nennen. K&R würden while(*dst++=*src++); schreiben. Irgendwie weigert sie sich, hübsch zu werden.



  • Wieso wird denn hier ständig this verwendet, wo es nicht nötig ist? Es bläht den Code unnötig auf, und das empfinde ich persönlich als schlecht lesbar.



  • Der aus dem Westen ... schrieb:

    Jedes mal, wenn jemand

    int * Pointer = new int [10];
    

    schreibt, möchte ich gleichzeitig heulen und den Programmierer strangulieren.

    Geht mir ähnlich. Aber waagerecht noch nicht so schlimm.
    Es gibt Leute, die machen es senkrecht!

    this->len=strlen(str);
    
    this->str=new char[this->len+sizeof(char)];
    
    //Ist doch so viel lesbarer und einfacher, oder?
    for(unsigned int i=0;str[i];i++)
        this->str[i]=str[i];
    
    this->str[this->len]=0;
    


  • Serious_Bob schrieb:

    Buch? 😃 Ne ich hab Kenntnisse in Java, C#, ABAP, PHP.
    Für C++ wollt ich mir nicht auch noch ein Buch kaufen 😉

    Ich sehe da keinen Zusammenhang. C++ ist eine völlig andere Sprache. Du tust so, als ob C++ nur ein Dialekt von anderen Dir bekannten Sprachen sei. Da irrst Du Dich aber gewaltig. Du kannst Dir mit einem guten C++ Buch viel Ärger und Zeit sparen. Zeit ist Geld. Glaub's mir, die Investition lohnt sich.

    Kompakte Grundausbilding:
    - Accelerated C++ (Andrew Koenig & Barbara E. Moo)
    - Effective C++ (Scott Meyers)

    Serious_Bob schrieb:

    Das einzige Problem ist, dass C++ halt sehr Prozessor nah ist und ich da erstmal durchsteigen muss.

    In C++ kannst Du Dir die Füße abschießen, ja. Umso wichtiger sind gute Bücher, die Dir die Konzepte der Sprache und bewährte Vorgehensweisen näher bringen.



  • volkard schrieb:

    Aber mir scheint, Du wolltest damit rohen Speicher besorgen.

    Ja, ich habe bereits gesagt, dass ich da Unsinn geschrieben habe. Ich gebe es zu.

    volkard schrieb:

    Und wenn man schon strlen benutzt, darf's auch ein bißchen memcpy sein.

    Hätte ich auch gleich tun können, dafür war ich aber schlichtweg zu faul.

    volkard schrieb:

    Die Schleife ist seltsam. Sie soll auf jeden Fall mindestens einen char kopieren? Der FI/AE würde das eine fußgesteuerte Schleife nennen. K&R würden while(*dst++=*src++); schreiben. Irgendwie weigert sie sich, hübsch zu werden.

    str[i] bedeutet, dass überprüft wird, ob in dem jeweiligen Element ein Nullterminierungszeichen steht. Wenn ja, wird die Schleife abgebrochen, und deshalb wird bei einem leeren String auch nur die 0 eingefügt. Die Anführungszeichen und den Schrägstrich spare ich mir, weil '\0' soweit ich weiß äquivalent zu 0 ist. Insofern würde ich (ohne weitere Kenntnisse darüber, wie hinterher der Maschinencode aussieht) sagen, dass die Schleife ihren Zweck sehr performant erfüllt, oder?

    @_matze: Ein Parameter von ihm heißt 'str', genauso wie ein Element. Ich hätte es auch rausnehmen können (und glaub' mir, ich war kurz davor), aber dann hat mich wieder die Faulheit übermannt.

    volkard schrieb:

    Geht mir ähnlich. Aber waagerecht noch nicht so schlimm.
    Es gibt Leute, die machen es senkrecht!

    Hat auch was von psychischer Folter, zumindest, wenn man Zwangsneurotiker ist.



  • Der aus dem Westen ... schrieb:

    @_matze: Ein Parameter von ihm heißt 'str', genauso wie ein Element. Ich hätte es auch rausnehmen können (und glaub' mir, ich war kurz davor), aber dann hat mich wieder die Faulheit übermannt.

    Das ist mir schon aufgefallen. Ich habe aber nach den Stellen gefragt, an denen this unnötigerweise verwendet wird. Und wenn man konsistent bleiben will, ist es wohl ratsamer, Member oder Parameter umzubenennen, anstatt an ausnahmslos jeder Stelle "this->" zu notieren. Das ist dann letzten Endes auch weniger Arbeit, also der Faulheit zuträglich. 😉



  • Der aus dem Westen ... schrieb:

    str[i] bedeutet, dass überprüft wird, ob in dem jeweiligen Element ein Nullterminierungszeichen steht. Wenn ja, wird die Schleife abgebrochen, und deshalb wird bei einem leeren String auch nur die 0 eingefügt. Die Anführungszeichen und den Schrägstrich spare ich mir, weil '\0' soweit ich weiß äquivalent zu 0 ist. Insofern würde ich (ohne weitere Kenntnisse darüber, wie hinterher der Maschinencode aussieht) sagen, dass die Schleife ihren Zweck sehr performant erfüllt, oder?

    Nicht performanter also mit dem Vergleich gegen den Nullterminator.
    Du läufst, solange str[i] wahr ist.
    Ich laufe, solange str[i] nicht der Nullterminator ist.



  • volkard schrieb:

    Nicht performanter also mit dem Vergleich gegen den Nullterminator.
    Du läufst, solange str[i] wahr ist.
    Ich laufe, solange str[i] nicht der Nullterminator ist.

    Und sofern mich meine kümmerlichen C/C++-Kenntnisse nicht trügen, ist wahr == (!Nullterminator) , oder? Der Nullterminator enthält ja den Wert 0, und der ist negativ, während jedes andere Zeichen positiv ist (zumindest, sofern mich mein Wissen um ASCII, den verschiedenen Codepages und den Unicode-Formaten nicht auf das Glatteis führen). Daher verstehe ich nicht ganz, was du mir sagen willst ...



  • Der aus dem Westen ... schrieb:

    volkard schrieb:

    Nicht performanter also mit dem Vergleich gegen den Nullterminator.
    Du läufst, solange str[i] wahr ist.
    Ich laufe, solange str[i] nicht der Nullterminator ist.

    Und sofern mich meine kümmerlichen C/C++-Kenntnisse nicht trügen, ist wahr == (!Nullterminator) , oder? Der Nullterminator enthält ja den Wert 0, und der ist negativ, während jedes andere Zeichen positiv ist (zumindest, sofern mich mein Wissen um ASCII, den verschiedenen Codepages und den Unicode-Formaten nicht auf das Glatteis führen). Daher verstehe ich nicht ganz, was du mir sagen willst ...

    Ich finde, daß meine Schreibweise eher Klartext ist, während Deine ein kleines Rätsel beinhaltet. Rätsel im Code sind böse meist. Es geht nicht darum, zu zeigen, daß man so vertraut mit C++ ist, daß man sowas normalerweise recht flüssig hinschreiben kann (das können wir alle). Es geht darum, daß man den Code auch noch stockbesoffen recht flüssig lesen kann.



  • Was mich immer noch wundert ist, dass es auf 3 Seiten keiner geschafft hat, die Initialisierungsliste ins Spiel zu bringen?

    class BOBString 
        { 
        public: 
            BOBString(const char *str); 
            ~BOBString(void); 
    
        private: 
            int len; // die Reihenfolge hab ich umgedreht,
            char *str; // sonst serviert einem der Compiler eine Warnung
        };
    
    BOBString::BOBString(const char* str) : len(std::strlen(str)), str(new char[len + 1])
    {
      // String kopieren
      // ...
    }
    

    Wo ich mir jetzt nicht sicher bin, ob strlen() für Null-Zeiger so funktioniert, dass 0 zurückgegeben wird, aber da kann man ja schnell mit ?: Abhilfe schaffen. 🤡



  • bmario schrieb:

    Wo ich mir jetzt nicht sicher bin, ob strlen() für Null-Zeiger so funktioniert, dass 0 zurückgegeben wird, aber da kann man ja schnell mit ?: Abhilfe schaffen. 🤡

    Wozu? Wer 0 übergibt, ist selber schuld. Fertig.


Anmelden zum Antworten