Speicherzugriffsfehler char*



  • Gideon schrieb:

    ...char test[] erzeugt keinen konstanten zeiger, sondern einen array. ein konstanter zeiger wäre char *const. was du eigentlich verwendest ist aber ein const char * bzw. char const *...

    Ist ein Array (z.B. char str[20]; ) nicht auch ein konstanter Zeiger, da die Anfangsadresse nicht veränderbar ist?

    Gruß



  • das stimmt. allerdings musst du zwischen konstanten zeigern und zeigern auf konstanten unterscheiden.

    const char *foo; // du darfst den zeiger ändern, aber nicht den inhalt
    *foo = 0; // fehler
    foo = "foo"; // ok
    
    char *const bar; // du darfst den inhalt ändern, aber nicht den zeiger
    *bar = 0; // ok
    bar = "bar"; // fehler
    

    so weit, so gut. aus irgendwelchen gründen erlaubt c/c++ nun aber dieses konstrukt

    char *qux = "qux"; // "qux" ist const char *, wird aber implizit zu char *
    *qux = 0; // boom! der inhalt von qux darf nicht geändert werden, aber es kompiliert trotzdem!
    


  • du meintest
    strf[2] = 'A'; // Das geht nicht
    statt "A" nehme ich an.

    dann erhalte ich auch nen speicherzugriffsfehler.

    mache ich dann
    char temp[]="Hallo Welt";
    draus, gehts.

    Hallo
    l
    HaAlo Welt
    

    es kommt nicht drauf an, daß die zeiger unveränderlich ist, sondern das das zeug, wo die zeiger draufzeigen unveränderlich ist.



  • Vielen Dank für die Antworten und das um diese Zeit.
    Jetzt ist es mir klar geworden.

    Ist das mit der Typenumwandlung vom Compiler abhängig und aus
    welchen Gründen wird diese vorgenommen?

    Danke!
    Grüße



  • matko schrieb:

    Vielen Dank für die Antworten und das um diese Zeit.
    Jetzt ist es mir klar geworden.

    Ist das mit der Typenumwandlung vom Compiler abhängig und aus
    welchen Gründen wird diese vorgenommen?

    Danke!
    Grüße

    typumwandlung? ka.
    aber ich erzähl dir, warum stringliterale konstant sind.

    der compiler macht ja aus

    char* hw="hello, world!";
    

    sowas wie

    //irgendwo im speicher zum beispiel an adresse 0x4711 stehen die
    //datenbytes "hello, world!"
    char* hw=0x4711;
    

    die datenbytes stehen so in der exe-datei und werden beim starten in den speicher geladen.

    dem compiler ist darüberhinaus erlaubt, aus

    char* hw="hello, world!";
    char* w="world!";
    

    ein pfiffiges

    char* hw="hello, world!";
    char* w=hw+7;
    

    zu machen. er faßt also strings zusammen, wenn es geht.

    schreibst du jetzt

    char* hw="hello, world!";
    char* w="world!";
    *w='W';
    

    dann haste BEIDE strings verändert.
    um sowas zu vermeiden, liegen die strings am besten in einem speichersegment, das als schreibgeschützt markiert ist. zum beispiel dort, wo der ausführbare maschinencode des programms liegt, der sollte auch schreibgeschützt sein, das wäre ganz nett.

    wenn du aber mit char hw[]="hello, world"; ein array of char auf dem stack anlegst, gehört es dir ganz alleine und ist eine kopie des strings aus dem schreibgeschützen speicher. entsprechend muß es auch immer wieder angelegt werden, was ein bißchen zeit kostet, aber nicht viel.



  • matko schrieb:

    Ist das mit der Typenumwandlung vom Compiler abhängig und aus
    welchen Gründen wird diese vorgenommen?

    Das ist Abwärtskompatibilität zu C ("damals" galten String-Literale noch als char* - und um alte C-Programme in C++ weiternutzen zu können, wurde die Umwandlung eines (const char*) String-Literals nach char* im C++ Standard genehmigt).

    PS: Ein Bonustip von mir: Nimm lieber std::string, da bist du auf der sicheren Seite.



  • CStoll schrieb:

    PS: Ein Bonustip von mir: Nimm lieber std::string, da bist du auf der sicheren Seite.

    mein tip: hör nicht drauf.



  • volkard schrieb:

    CStoll schrieb:

    PS: Ein Bonustip von mir: Nimm lieber std::string, da bist du auf der sicheren Seite.

    mein tip: hör nicht drauf.

    Was soll so eine scheiss Antwort? Begründung bitte!



  • Was hast du gegen std::string? Ehe ich mich mit der Speicherverwaltung und -Sicherheit rumschlage, verwende ich lieber eine Klasse, die das für mich erledigt.



  • CStoll schrieb:

    Was hast du gegen std::string? Ehe ich mich mit der Speicherverwaltung und -Sicherheit rumschlage, verwende ich lieber eine Klasse, die das für mich erledigt.

    mir scheint, matko arbeitet sich gerade toll in zeiger und so ein. ist das nicht wunderbar?
    ok, klar soll er bei den meisten sachen umsteigen, kommt immer auf das programm an.



  • Danke für die echt ausfürlichen Antworten.
    Natürlich ist das Arbeiten mit c++ strings einfacher, aber es gibt nunmal auch Vorgaben das man numr mit Zeigern arbeiten darf (durch den Prof z.B 😉 ).
    Das Verstehen und Anwenden mit Zeigern mit den großen Möglichkeiten ist für mich von Interesse.

    Gruß & Thx
    matko



  • matko schrieb:

    Ist ein Array (z.B. char str[20]; ) nicht auch ein konstanter Zeiger

    Nein, ist es nicht und wird es auch niemals sein. Ein Array ist nunmal kein Zeiger. Ein Compiler darf aber bei Bedarf ein Array in einen Zeiger auf das erste Element umwandeln. Dieser Zeiger kann, muss aber nicht konstant sein.


Anmelden zum Antworten