wieder mal ein paar char Probleme...



  • naja du hast recht, auf den ersten Blick ist es ein Pointer, was es natürlich auch immer bleiben wird. Die Lösung des Problems ist folgendes:

    Ein Pointer ist ja einfach nur eine Speicheraddresse. Und zwar handelt es sich bei einem Pointer um die Addresse im Speicher, bei der das erste Byte der Variablen liegt, auf die der Pointer zeigt.

    Hast du also einen char* der 5 char elemente reserviert, dann zeigt dieser zeiger auf den ersten char. Das du an alle anderen Elemente rankommst, liegt daran, dass du im gegensatz zu einer Referenz den Zeiger neu initialisieren kannst, also du kannst ihn auf die anderen Elemente setzen. Das machst du normalerweise, indem zu wie auf einen Array auf die Elemente zugreifst. Im Speicher passiert dann in etwa sowas:

    char* ptr = new char [10];
    strcpy ((char*), ptr, (char*)"hello world");
    
    //zugriff auf das erste element direkt über den zeiger
    char test = ptr[0];   //über den Array
    char test = *ptr;     //über den Zeiger, weil ptr auf die daten an ptr[0] zeigt
    
    //zugriff auf das n-te Element
    int n = 4;
    char test = ptr[n];    // Zugriff über Array
    char test = *(ptr + n * sizeof (char));   //Zugriff über Zeiger über Verschiebung
    

    Wenn Du jetzt sowas machst:

    char* ptr = "hello world";
    

    dann wird intern speicher schon reserviert. In dem Fall 5 (für das hello) 6 (für das " welt") und 1 für das \n macht 12 Character. Wenn du jetzt versuchst noch was in die Zeichenkette zu schreiben, wird dies fehlschlagen. Kannst es ja mal versuchen.

    Ich hoffe der kleine Exkurs hat geholfen.

    Gruß Sebastian



  • ja sogar sehr, danke euch beiden, so etwas steht leider nie in irgendeinem Buch...



  • Hi,

    valide:

    const char* a = "Hallo";
    

    invalide:

    char* a;
    a = "Hallo";
    

    Ich könnte mir vorstellen, dass der Compiler das so optimiert, dass da char* a = "Hallo" steht und das daher funktioniert, aber eigentlich ist sowas nicht möglich.

    MfG Eisflamme



  • Mis2com schrieb:

    invalide:

    char* a;
    a = "Hallo";
    

    Falsch. Schlechter Stil, aber nicht "invalide".

    Ich könnte mir vorstellen, dass der Compiler das so optimiert, dass da char* a = "Hallo" steht und das daher funktioniert, aber eigentlich ist sowas nicht möglich.

    😕



  • Hi,

    nö? wieso geht das?
    wie lange lebt "hallo" denn?

    MfG Eisflamme



  • "hallo" ist ein Stringliteral und lebt somit über die gesamte Dauer der Programmausführung.



  • Hi,

    wo lebt so ein Literal denn, dass es so lange lebt? Und wieso ist das dann schlechter Stil?

    fg Eis



  • Seltsame Fragen stellst du, wo du doch gerade noch als valide bezeichnet hattest, einen const char* auf ein Stringliteral zu setzen.

    Was meinst du damit, wo es lebt? Dazu macht der Standard keine Aussage. Ich würde sie im Datensegment ablegen, ungefähr dort, wo auch die globalen und statischen Variablen liegen. Der gcc legt Stringliterale in einem Read-Only-Speicherbereich ab.

    Was auch gleich beantwortet, warum es schlechter Stil ist, einen char* auf ein Literal zeigen zu lassen. Das Verändern das Literals führt zu undefiniertem Verhalten, also sollte man davon absehen, und nur const char* darauf zeigen lassen, damit der Compiler sowas gleich abfängt. Aus Kompatibilitätsgründen zu C gibt es aber eine automatische const char* zu char* Umwandlung in C++, die m.W. allerdings auf Literale beschränkt ist.



  • Hi,

    ok, danke, jetzt ist mir das klar.
    Wegen const char* chfff = hatte ich gehört, dass manche Compiler das wohl auch so optimieren würden, dass für chfff dann auch gleich Speicher belegt wird und das reinKOPIERT wird, also so als Feature, aber k.A.

    MfG Eisflamme



  • Mis2com schrieb:

    Wegen const char* chfff = hatte ich gehört, dass manche Compiler das wohl auch so optimieren würden, dass für chfff dann auch gleich Speicher belegt wird und das reinKOPIERT wird, also so als Feature, aber k.A.

    Klingt eher nach einer Pessimierung 😃
    Was soll das bringen? Die Allokation dauert doch nur, und wer gibt das dann frei? Verwechselst du das vielleicht hiermit:

    const char foo[6] = "hallo";
    


  • Bashar schrieb:

    Seltsame Fragen stellst du, wo du doch gerade noch als valide bezeichnet hattest, einen const char* auf ein Stringliteral zu setzen.

    Was meinst du damit, wo es lebt? Dazu macht der Standard keine Aussage. Ich würde sie im Datensegment ablegen, ungefähr dort, wo auch die globalen und statischen Variablen liegen. Der gcc legt Stringliterale in einem Read-Only-Speicherbereich ab.

    Japp. Dort wird jedes Literal maximal einmal in einer Tabelle abgelegt. Kann man auch leicht prüfen:

    #include <iostream> 
    using namespace std; 
    
    int main() { 
       const char * c1, *c2, *c3;
       c1 = "hallo";
       c2 = "hallo";
       c3 = "Hallo";
       cout << (c1==c2) << endl;  // 1
       cout << (c1==c3);          // 0
       cin.get();
       return 0;
    }
    


  • Hi,

    Bashar:
    Genau. 🙂

    MfG Eis


Anmelden zum Antworten