Verständnisproblem char * vs char s[]



  • Hallo allerseits,

    habe hier ein Verständnisproblem. Und zwar verstehe ich nicht, warum folgendes geht:

    char *p;
     *p = "string";
    

    Zwar meckert der Compiler, aber es funktioniert.
    Nur wo wurde denn jetzt genau Speicher reserviert oder anders:
    Woher weiss p wo er hinzeigen soll?
    Dass das funktioniert, deckt sich irgendwie nicht mit dem von mir bereits
    Erlerntem. Oder ich habe die Sache mit den Pointern immer noch nicht begriffen.

    Dankebar für Erklärungen,
    robn9



  • robn9 schrieb:

    char *p;
     *p = "string";
    

    Zwar meckert der Compiler, aber es funktioniert.
    Nur wo wurde denn jetzt genau Speicher reserviert oder anders:
    Woher weiss p wo er hinzeigen soll?

    Gar nicht. p ist uninitialisiert, d.h. er enthält mehr oder weniger zufälligen Müll. Je nachdem, wo p nun gerade tatsächlich hinzeigt, können bei sowas die wunderlichsten Dinge passieren.

    Dass das funktioniert, deckt sich irgendwie nicht mit dem von mir bereits
    Erlerntem. Oder ich habe die Sache mit den Pointern immer noch nicht begriffen.

    "Funktionieren" ist relativ 🙂 Es ist trotzdem ein Fehler. Ach ja übrigens ... die Warnung des Compilers bezieht sich nicht darauf, dass p uninitialisiert ist. Die hat was damit zu tun, dass *p ein einzelnes Zeichen (das an der Stelle, an die p zeigt) symbolisiert, du aber versuchst, dem einen String zuzuweisen. Strings sind Arrays, also wird hier die Anfangsadresse eines Strings in einen char umgewandelt und nach *p geschrieben. Das ist offensichtlich nicht ganz koscher, deshalb warnt der Compiler.



  • Du meinst vermutlich das:

    char *p; 
     p = "string";
    

    Das macht sinn, dabei zeigt p auf "string".



  • Man darf nur nicht vergessen, dass auch hier kein Speicher "reserviert" wird. Also reinschreiben is nicht.



  • sorry, ich meinte:

    char *p; 
     p = "string";
    

    aber damit geht reinschreiben eben doch, obwohl kein Speicher reserviert wurde
    Damit würde doch meine Frage weiter bestehen - oder? Denn wie kann p auf "string" zeigen, wenn "string" in keiner variable steckt - also für "string" kein Speicher reserviert wurde? Es wird doch bestimmt nicht automatisch ein array angelegt, wenn ein pointer auf ein character deklariert wird. Versteht Ihr, was ich meine bzw. nicht verstehe???



  • Also erstmal pointet "p" auf irgendeine speicheradresse, da du den pointer ja nicht mit NULL oder sonstwas initialisiert hast... danach werden 6 Byte Speicher für deinen String "string" angefordert und p danach als Pointer auf diesen Bereich initialisiert! Ist doch alles in Ordnung... 😉



  • Doch, es wird ein Array angelegt. Allerdings ist das nicht zum reinschreiben bestimmt, wenn du damit arbeiten willst, musst du eine Kopie machen. Beispielsweise könnte der Compiler für "string" bei mehrmaligem Auftauchen nur einmal Platz anlegen. Oder angenommen, du hast sowohl "string" als auch "ring" im gleichen Programm, dann darf er die Strings überlappend anlegen. Und zu guter Letzt darf er die Strings auch in einem read-only-Speicherbereich ablegen.

    Stringliterale haben statische Speicherdauer, d.h. sie werden beim Start des Programms angelegt und initialisiert und bestehen bis zum Ende.



  • alpha one schrieb:

    ... danach werden 6 Byte Speicher für deinen String "string" angefordert ... 😉

    Das genau hätte ich nach meinem Verständnis anders gesehen,
    denn dann hätte der Code doch so lauten müssen:

    char s[7];
     strcpy(s, "string");
    


  • Danke Bashar!!!
    Die Antwort erklärt mir auch das Verhalten von einigen Testläufen.
    Also nochmal danke !!!



  • Hmmm.... ich bin zwar erst seit 4 Wochen am C programmieren, habe vorher jahrelang nur auffem assembler (68k) gecoded aber ich würde es trotzdem anders sehen.... 😉
    ich meine char s[7]; legt einen speicherbereich über 7 bytes an, der erstmal allerdings leer oder sonst wie zugemüllt ist. Da du jetzt erst deinen String "string" in diesen reservierten speicherbereich mit strncpy reinkopierst, hat der String "string" ja letztendlich schon irgendwo im Speicher gestanden, sonst hätte ihn strncpy ja nicht kopieren können! D.h dein String müsste nach der Kopieraktion in dein Char-Array ja zweimal im Speicher stehen.... also wieso nicht gleich einen Pointer auf den String mit char *p="HALLO!" zuweisen???? Ok, klärt mich auf wenn ich da was falsch verstehe! 🙂



  • Völlig richtig. Du hattest aber vorher geschrieben, die 6 Bytes würden erst in dem Moment reserviert, indem der Pointer zugewiesen wird. Das kann natürlich nicht sein.
    BTW das Problem an char *p = "string" ist, wie ich schon schrub, dass String-Literale als read-only anzusehen sind.



  • ...das hab ich jetzt auch verstanden... cool, danke!

    ps: "schrub" ist auch nicht schlecht hehe! 🙂


Anmelden zum Antworten