Geschützter Speicher char pointer



  • Hallo zusammen,

    Sorry falls es das Thema schon mal gab. Habe es so aufgelöst nicht gefunden.

    Mir ist klar, dass:

    char * chZeiger = "Hallo";
    chZeiger [0] = 'h';
    

    zum Absturz des Programmes führt, da sich ja wenn ich es richtig verstehe die Daten für Hallo im geschützten Speicher befinden.

    Auch:

    cout << chZeiger[99];
    

    ist noch nachvollziehbar. Hier wird auf irgendetwas im Speicher gezeigt, was natürlich in diesem Fall keinen Sinn macht.

    Was mich irritiert ist, dass:

    chZeiger [99] = 'h';
    

    auch abbricht. Eigentlich benötigt man hier doch nur 5 Zeichen (für Hallo)und ein \n zur Terminierung.

    Wie viel Platz wird jetzt für Hallo im geschützten Speicher reserviert?
    Ist der geschützte Speicher auf dem Stack, auf dem Heap oder ist dies ein komplett anderes Konzept?

    Besten Dank schon mal.

    Grüße



  • Nestor81 schrieb:

    Eigentlich benötigt man hier doch nur 5 Zeichen (für Hallo)und ein \n zur Terminierung.

    Genau. Und deswegen ist chZeiger[99] kein erlaubter Zugriff



  • Nestor81 schrieb:

    Ist der geschützte Speicher auf dem Stack, auf dem Heap oder ist dies ein komplett anderes Konzept?

    Ja.
    Der Standard definiert das nicht.

    Aber meist Letzteres.
    Die Daten liegen meist im Data-Segment. Und das ist komplett für den Schreibzugriff gesperrt.



  • Nestor81 schrieb:

    char * chZeiger = "Hallo";
    chZeiger [0] = 'h';
    

    Über Deine Frage hinaus noch folgendes:

    Dein Compiler sollte Dich schon warnen, dass Dein Code da ein Problem hat. Aktivier Warnungen in Deinem Compiler.

    Mein Compiler meint beispielsweise:

    test.cc:2:21: warning: ISO C++11 does not allow conversion from string literal to 'char *'
    [-Wwritable-strings]
    char * chZeiger = "Hallo";

    "Hallo" ist nämlich per definitionem ein ein const char[6] , deswegen muss chZeiger auch vom Typ const char* sein ("Zeiger auf const char").

    Wenn Du das berücksichtigst, kompiliert aber die Zuweisung in der Folgezeile nicht mehr: et voilá.



  • DirkB schrieb:

    Nestor81 schrieb:

    Ist der geschützte Speicher auf dem Stack, auf dem Heap oder ist dies ein komplett anderes Konzept?

    Ja.
    Der Standard definiert das nicht.

    Aber meist Letzteres.
    Die Daten liegen meist im Data-Segment. Und das ist komplett für den Schreibzugriff gesperrt.

    Wird der geschützte Speicher über den Windowsdienst "ProtectedStorage" verwaltet?
    Oder noch allgemeiner ist das Ganze abhängig vom OS?


  • Global Moderator

    Wie das ganze genau implementiert ist, wird vom C++-Standard nicht festgelegt. Er verlangt noch nicht einmal zwingend, dass es nicht funktionieren dürfte. In der Praxis wird es vom Speicher- bzw Executablemodell des jeweiligen Systems abhängen. Wie der momentane Standard bei einem modernen Windows (das wird auch von der OS-Version abhängen!) aussieht, weiß ich nicht aus dem Kopf. Ich bezweifle aber, dass dies über ProtectedStorage läuft; ProtectedStorage ist eher ein high-level Dienst für Anwendungen. Das wird wahrscheinlich eher über low-level Mechanismen des Betriebssystems bezüglich der Speichervirtualisierung laufen.



  • Alle bekannten modernen Betriebssysteme (Linux, Windows, OSX etc) verwenden Virtual Memory. Virtuelle Adressen werden ueber Page Tables auf physikalische Adressen abgebildet. Jeder Schreibe/Lesezugriff auf eine virtuelle Speicheradresse im Programm muss ueber diese Page Tables auf eine physikalische Adresse abgebildet werden.

    In disen Pagetables gibt es fuer jede Page (unter anderem) zwei Bits R und W, die fuer Read und Write stehen. Bei jedem Schreib- oder Lesezugriff wird ueberprueft, ob die Bits W bzw. R gesetzt sind. Viele Prozessoren bieten Hardware Unterstuetzung an (siehe z.B. MMU bei Intel), damit das ganze effizient ist.

    Unter Linux kommen String Literale wie in deinem Code zum Beispiel in die .rodata Section (siehe ELF Format), in der nur lesen erlaubt ist. In Windows ist das aehnlich, siehe PE (Portable Executable) File Format.



  • In Ordnung hab es soweit verstanden.

    Gibt es irgendwo eine Übersicht, durch welche Konzepte (im Code) etwas im geschützen Speicher landet oder ist das der einzige Fall mit dem char pointer?