Verständnissproblem bei char*



  • Oha das ging Fix 😃 Danke dafür erstmal. Das heist also ich erstelle zwar einen Array aber nur solange bis der Speicherblock voll ist?(Demnach danach eine Overflow?)
    Hoffe ich hab das jezt richtig verstanden 😛



  • RaXeph0n schrieb:

    War immer der Meinung ein Array wird mit char[] erstellt. ???

    Im Prinzip korrekt.
    Aber
    "hallo"
    muss ja auch irgendwo stehen.

    Wenn du cout<<"hallo welt"; schreibst, muss "hallo welt" ja irgendwo im Speicher stehen damot cout es ausgeben kann.

    mit
    char* p;
    p="hallo welt";
    sagst du nichts anderes als:
    hier hab ich einen char* namens p. Lass den doch mal bitte auf die Speicherstelle zeigen wo "hallo welt" drinnen steht.



  • Skym0sh0 schrieb:

    char * lol = "hahaha";
    char arr[] = "trololol";
    

    ist dasselbe.

    Das ist keineswegs dasselbe! In arr wird eine Kopie des Strings angelegt. Man darf die Werte ändern. lol zeigt aber auf die Stringkonstante. Änderungen im String sind nicht erlaubt. Gute Compiler sollten auch mit einer Warnung darauf hinweisen.



  • oh, stimmt jetzt wo dus sagst xD

    ja das waren die kosntanten string literale, die irgendwo (je nach architektur) am anfand des programms im datensegment stehen und nicht verändert werden können/dürfen/müssen/sollen



  • Jo. Also, das das eine ein Pointer ist, der auf eine Speicheradresse verweist, war mir auch vorher schon bewusst.
    Ich verstehe nur nicht wieso ich mit einem char Pointer plötzlich einen string speichern kann.
    Was genau passiert hier? Wird jetzt ein Array angelegt oder nicht?
    Bitte beantwortet mir auch die Frage vorher, mit dem Speicherblock.
    (Ist ja schon interessant xD) 🙂



  • RaXeph0n schrieb:

    Jo. Also, das das eine ein Pointer ist, der auf eine Speicheradresse verweist, war mir auch vorher schon bewusst.
    Ich verstehe nur nicht wieso ich mit einem char Pointer plötzlich einen string speichern kann.
    Was genau passiert hier? Wird jetzt ein Array angelegt oder nicht?
    Bitte beantwortet mir auch die Frage vorher, mit dem Speicherblock.
    (Ist ja schon interessant xD) 🙂

    etwas vereinfacht:

    "hallo"
    ist quasi das selbe wie
    7

    Wenn du
    int i=7;
    schreibst, dann wird 7 in die Variable i kopiert.

    Wenn du
    char* p="hallo";
    schreibst, wird die adresse von "hallo" in die Variable p kopiert.

    Schreib mal eine Hello World Programm und öffne die .exe Datei dann mit einem Texteditor. Du wirst viel Schrott sehen (den Maschinencode) aber auch die Zeichenketten die du im Code definiert hast. Also irgendwo steht "Hallo Welt".

    Und mit
    char* p="Hallo Welt";
    holst du dir nun die Position auf der "Hallo Welt" steht und speicherst sie in p rein.

    Da wird kein Array angelegt und kein Speicher reserviert und kein Speicherleck entsteht.



  • Hmm, weis nich ob du das richtige meinst, aber die Aussage war nicht ganz korrekt, wenn ich p nämlich Ausgebe bekomme ich nicht die Speicheradresse ausgegeben sondern "Hallo Welt!".
    Da dieser String ja nur exemplarisch für eine Usereingabe steht, ist dieser ja eigentlich noch nirgends vorhanden.
    Das ist auch was mich verwirrt. (Okay und um weiterer Verwirrung meinerseits vorzubeugen, mit dem Typ char kann ich EINEN character abspeichern oder?)



  • RaXeph0n schrieb:

    Hmm, weis nich ob du das richtige meinst, aber die Aussage war nicht ganz korrekt, wenn ich p nämlich Ausgebe bekomme ich nicht die Speicheradresse ausgegeben sondern "Hallo Welt!".
    Da dieser String ja nur exemplarisch für eine Usereingabe steht, ist dieser ja eigentlich noch nirgends vorhanden.
    Das ist auch was mich verwirrt. (Okay und um weiterer Verwirrung meinerseits vorzubeugen, mit dem Typ char kann ich EINEN character abspeichern oder?)

    In C++ kann man Funktionen überladen. Im Falle von cout handelt es sich hier um operator<< . Es gibt hierbei eine Überladung für char const* , die diesen Typen anders behandelt (besagte Ausgabe als String) als andere Zeigertypen.

    Ein Pointer speichert auch keinen String. Wenn Du folgendes schreibst:

    char * s = "blub";
    

    Dann gibt es irgendwo im Programm fest eingebrannt einen Speicherbereich der "blub" enthält. Der Pointer s zeigt auf diesen Speicherbereich enthält also dessen Adresse. Du darfst den Speicherbereich aber nicht ändern, weil er, wie gesagt, fest eingebrannt ist. Deshalb ist es auch besser, gleich char const * s = "blub" zu schreiben. Normalerweise warnen aktuelle Compiler auch, wenn man das nicht macht.

    Wenn Du allerdings folgendes schreibst:

    char s[] = "blub";
    

    dann unterscheidet es sich wie folgt:
    Es gibt ebenfalls den Speicherbereich mit "blub" der irgendwo fest eingebrannt ist, allerdings wird der Inhalt des Bereichs beim Programmstart in das Array s vom Typ char[5] kopiert. An den ursprünglichen Speicherbereich kommst Du nicht mehr ran, da Du keinen Pointer darauf hast. Das Array selbst liegt, je nachdem wo Du es definiert hast, im globalen oder im automatischen Speicher welcher Dir gehört, weshalb Du es (das Arrays) ändern darfst.



  • RaXeph0n schrieb:

    Da dieser String ja nur exemplarisch für eine Usereingabe steht,

    Nein, steht er nicht. Und wenn du eine Frage zu einer Usereingabe hast, solltest du auch genau diese Frage stellen und nicht eine ganz andere!

    Grundsätzlich: Vermeide char* und char-Arrays in C++ (gerade als Anfänger!) und benutze std::string!



  • Uhh ja mit Usereingabe funktioniert es nichtmehr. Langsam kommen wir der Sache näher.
    (Und nein meine Frage hatte Prinzipiell überhaupt nichts mit Usereingaben zu tun, und Sinn dieses Threads ist es auch nicht das mein Programm richtig läuft sondern das ich verdammt nochmal verstehe wieso ein Pointer vom Typ char in der lage ist mehrere chars einzulesen(okay vielleicht das falsche wort nehmen wir einfach mal "zu verarbeiten") obwohl der Datentyp das garnicht unterstüzt. Daraufhin sagen die Leute mir, hey,

    char* dest="test";
    

    zeigt auf die Adresse von "test" und speichert die in "dest".
    Wenn ich nun aber "dest" Ausgebe steht in "dest" nicht zB. "0x0eeffe5" sondern "test". Also ist diese Aussage schlichtweg falsch.
    Bzw die Leute meinen bestimmt das Richtige aber für mich als Anfänger ist das nicht logisch und mega verwirrend.)
    War jetzt auch nicht böse gemeint ihr wollt mir ja nur helfen xD
    Nur immo is das Fragezeichen in meinem Gesicht noch größer als vor dem Post 😃

    Also greife ich mit char* auf den Speicher zu der "Test" enthält weil "Test" ja schon fest als Zeichenkette in meinem Quellcode steht und somit irgendwo abgespeichert sein muss?
    Hoffe das ist jetzt richtig 😃

    (Und spielt es eigentlich eine Rolle ob ich z.B.

    char* z;
    char * z;
    

    oder

    char *z
    

    schreibe?.)

    Also was im Grunde mein Problem ist, ist das ich Sachen gerne ERST verstehe und DANN anwende. Und ich meine wirklich verstehe und nicht nur , ah okay das macht dieses und jenes. Sondern ich will die Logik dahinter begreifen.



  • RaXeph0n schrieb:

    [...] Sondern ich will die Logik dahinter begreifen.

    Meinen Beitrag hast Du gelesen, ja?



  • RaXeph0n schrieb:

    Wenn ich nun aber "dest" Ausgebe steht in "dest" nicht zB. "0x0eeffe5" sondern "test".

    Das liegt daran, dass char-Zeiger eine Sonderbehandlung bekommen. Alle Ausgabemechanismen gehen bei char-Zeigern davon aus, dass sie auf einen mit einem Nullzeichen terminierten String im Speicher zeigen. Es wird also automatisch nicht die im Zeiger gespeicherte Adresse, sondern der Speicherinhalt dieser sowie aller folgenden Adressen ausgegeben, bis die Endmarkierung angetroffen wird.



  • MFK schrieb:

    RaXeph0n schrieb:

    Wenn ich nun aber "dest" Ausgebe steht in "dest" nicht zB. "0x0eeffe5" sondern "test".

    Das liegt daran, dass char-Zeiger eine Sonderbehandlung bekommen. Alle Ausgabemechanismen gehen bei char-Zeigern davon aus, dass sie auf einen mit einem Nullzeichen terminierten String im Speicher zeigen. Es wird also automatisch nicht die im Zeiger gespeicherte Adresse, sondern der Speicherinhalt dieser sowie aller folgenden Adressen ausgegeben, bis die Endmarkierung angetroffen wird.

    Oh mein Gott! Danke!
    Genau DAS, hab ich gebraucht. Bis zur Endmarkierung, Sonderbehandlung. Danke!
    Over and Out!

    Edit: Gibts einen "Danke" Button hier im Forum oder so? xD


Anmelden zum Antworten