das “Hallo Welt” ist tatsächlich im Nur-Lese-Speicher gespeichert.
Ich bin nicht so klar über den Nur-Lese-Speicher. Was ist die Erklärung? Ist das wie ein Flag für den Compiler, das den Compiler anweist, nicht in diesen Abschnitt zu schreiben?
Haben Sie eine Referenz? Ich denke, du meinst vielleicht: const char* s = “hello world”.
– Jakob Schwarz
10. November 2009 um 0:29 Uhr
Es ist nicht klar, dass alle Prozessorarchitekturen geschützten Speicher unterstützen.
– Jldupont
10. November 2009 um 0:30 Uhr
@James Black: Das OP spricht offensichtlich über das Zeichenfolgenliteral "hello world"die tatsächlich im Nur-Lese-Speicher gespeichert werden können, unabhängig davon, wie der Zeiger deklariert ist.
Ich bin auch neugierig, wenn wir eine Konstante deklarieren, z. B.: const int a; wird a auch in den Nur-Lese-Speicherbereich zugewiesen? (weil es konstant ist, nicht änderbar, also gehe ich davon aus)
– Benutzer188276
10. November 2009 um 0:41 Uhr
Nils Pipenbrink
Das ist kein Merkmal des C Sprache sondern eine Funktion des Compilers/Linkers und des Betriebssystems, die zusammenarbeiten.
Wenn Sie solchen Code kompilieren, passiert Folgendes:
Der Compiler fügt die Zeichenfolge in einen schreibgeschützten Datenabschnitt ein.
Der Linker sammelt alle Daten in solchen schreibgeschützten Abschnitten und fügt sie in ein einzelnes Segment ein. Dieses Segment befindet sich in der ausführbaren Datei und ist mit einem “nur lesen”-Attribut gekennzeichnet.
Jetzt kommt der ausführbare Loader des Betriebssystems. Es lädt die ausführbare Datei (oder bildet sie in den Speicher ab, um genauer zu sein). Sobald dies erledigt ist, geht der Lader die Abschnitte ab und legt Zugriffsberechtigungen für jedes Segment fest. Für ein schreibgeschütztes Datensegment wird höchstwahrscheinlich die Codeausführung und der Schreibzugriff deaktiviert. Code (z. B. Ihre Funktionen) erhält Ausführungsrechte, aber keinen Schreibzugriff. Gewöhnliche Daten wie statische Variablen erhalten Lese- und Schreibzugriff und so weiter …
So machen es moderne Betriebssysteme.
Wie gesagt, es ist kein Feature der C-Sprache. Kompiliert man das gleiche Problem zB für DOS, läuft zwar das Programm, aber es wäre kein Schreibschutz möglich, weil der DOS-Loader keine Read-Only-Sections kennt.
Setzt die konstante Variable auch den gleichen Abschnitt wie “Hallo Welt”? ( Bsp.: const int a = 6 )
– Benutzer188276
10. November 2009 um 1:12 Uhr
“Es hängt davon ab, ob”. Das einzige, was Sie mit Sicherheit über eine Konstante int sagen können, ist, dass der Compiler eine Diagnosemeldung erzeugt, wenn Sie versuchen, sie zu ändern. Es kann in einem schreibgeschützten Abschnitt gespeichert werden, oder es wird möglicherweise überhaupt nie gespeichert und direkt als Konstante in die Anweisungen codiert, die es verwenden.
– Markus Bessey
10. November 2009 um 1:21 Uhr
@tsubasa – wahrscheinlich nicht und schon gar nicht wenn a ist ein Einheimischer. Aber was auch immer die Antwort ist, es hängt auch vom Betriebssystem und dem Ladeprogramm ab.
– Stefan C
10. November 2009 um 1:24 Uhr
Denken Sie auch daran, dass die Konstante sogar und höher in einem ROM sein kann. (Im Falle eines eingebetteten Programms.)
– Prof. Falken
10. November 2009 um 9:31 Uhr
@Nils Pipenbrinck Gibt es eine Möglichkeit, einen Compiler zu erzwingen, um das gesamte Programm einzufügen beschreibbar Erinnerung?
– phimuemue
28. Juli 2011 um 17:27 Uhr
Ausführbare Dateien bestehen aus zwei Teilen: einem .data-Abschnitt, der globale Variablen enthält, und einem .text-Abschnitt, der den eigentlichen Maschinencode enthält.
Zeichenfolgen werden in den .data-Abschnitt gestellt. Was C tut, wenn es „Hello world“ sieht, ist, dass es die Zeichenfolge „Hello world“ in die ausführbare Datei selbst einfügt und die Instanz von „Hello world“ im Programm durch die Adresse ersetzt, an der diese Zeichenfolge geladen wird.
Allerdings bin ich mir nicht sicher, warum es schreibgeschützt ist – theoretisch sollte ein Programm in der Lage sein, seinen eigenen Speicher zu ändern.
Nicht alle Prozessoren und Betriebssysteme unterstützen selbstmodifizierenden Code. Tatsächlich enthalten die meisten modernen Betriebssysteme als Sicherheitsfunktion einen Schutz vor selbstmodifizierendem Code.
– Absturz
10. November 2009 um 0:50 Uhr
String-Literale können und werden häufig im Textabschnitt gespeichert, da sie nicht modifizierbar sein müssen.
– Café
10. November 2009 um 1:09 Uhr
Echter Nur-Lese-Speicher wird durch das Speichersubsystem des Betriebssystems implementiert. Das Betriebssystem kann bestimmte Seiten als schreibgeschützt markieren.
In der Binärdatei kann der Compiler dem Betriebssystem mitteilen, welche Teile der ausführbaren Datei in Nur-Lese- oder Lese-Schreib-Speicherseiten platziert werden sollen.
hmmm … echter Speicherschutz wird auf Prozessorebene implementiert.
– Jldupont
10. November 2009 um 0:33 Uhr
@jldupont: Der Speicherschutz ist zwar auf Hardwareebene implementiert (zumindest in x86), aber die Ersteinrichtung erfolgt durch das Betriebssystem, dh es ist das Betriebssystem markiert Nur-Lese-Seiten als solche, und dann erzwingt die Hardware die vom Betriebssystem eingerichteten Nur-Lese-Markierungen.
– AnT steht zu Russland
10. November 2009 um 0:43 Uhr
@AndreyT: natürlich … mein Punkt war in Bezug auf @R Samuel. Ohne Hardware- Unterstützung, es gibt so viel, was man auf der Softwareebene tun kann.
– Jldupont
10. November 2009 um 0:50 Uhr
@R – Tatsächlich kann auf eingebetteten Systemen der Nur-Lese-Speicher tatsächlich mit ROM-Hardware implementiert werden. zB mit EPROM-Chips.
– Stefan C
10. November 2009 um 1:28 Uhr
sneha maganahalli
Wenn du schreibst char s[10]="sneha"; Sie weisen Ihrer Objektdatei 10 Byte Speicherplatz zu (kein Speicher, Speicher kommt nur ins Bild, wenn Sie Ihr Programm ausführen). Dies ist eine statische Speicherzuweisung (zur Kompilierzeit).
Aber wenn du schreibst char *s="sneha"; Sie weisen keinen Speicherplatz zum Speichern zu "sneha". Es wird im Abschnitt NUR LESEN gespeichert. Aber der Zeiger s wird in einem anderen Abschnitt gespeichert, je nachdem, wo es deklariert ist. Aber es zeigt auf die READ ONLY DATA "sneha". Wenn Sie also versuchen, darauf zu schreiben, erhalten Sie einen Segmentierungsfehler.
Zum Beispiel:
char *s = "sneha";
s[1] = 'N';
printf("%s",s); // you expecting output sNeha,
// but you get a seg fault since it is READ ONLY DATA
und schau, ob es “hello w0rld” sagt, wenn du anrufst
puts(s);
Wenn es einen sofortigen Segmentierungsfehler oder eine Datenausführungsverhinderungs-Ausnahme verursacht, ist es wahrscheinlich schreibgeschützt. (Wenn das System Sie damit durchkommen lässt, ist es keine gute Idee.)
Markus Bessey
Wie andere Leute bereits erwähnt haben, wird durch das Betriebssystem, den Compiler und die Chiparchitektur bestimmt, ob der Inhalt konstanter Zeichenfolgen im Nur-Lese-Speicher gespeichert wird.
Genauer gesagt legt der C-Standard fest, dass die Zeichenfolgen in Anführungszeichen “const char” haben[]” schreiben (oder entsprechende Worte, ich habe den Standard nicht zur Hand).
Jeder Code, der versucht, den Inhalt einer solchen Zeichenfolge zu ändern, ruft ein undefiniertes Verhalten auf. Das bedeutet, dass an diesem Punkt buchstäblich alles passieren kann, und der Anbieter des Compilers muss nicht einmal dokumentieren, was passieren kann.
In der Praxis bedeutet dies, dass ein C- oder C++-Programm, das portierbar sein möchte, vermeiden muss, konstante Zeichenfolgen zu ändern.
Im Allgemeinen erlaubt Ihnen der Compiler nicht, den Inhalt von “const”-Variablen zu ändern, daher können Sie “const” in den meisten Fällen als “schreibgeschützt” betrachten. Leider gibt es eine spezielle Ausnahme für char * und const char *, hauptsächlich aus historischen Gründen. Das bedeutet, dass Code so lautet:
char *x = "Hello, World";
*x = 'h';
wird ohne Fehler oder Warnung kompiliert, obwohl es undefiniertes Verhalten aufruft.
13691800cookie-checkWie ist der Nur-Lese-Speicher in C implementiert?yes
Haben Sie eine Referenz? Ich denke, du meinst vielleicht: const char* s = “hello world”.
– Jakob Schwarz
10. November 2009 um 0:29 Uhr
Es ist nicht klar, dass alle Prozessorarchitekturen geschützten Speicher unterstützen.
– Jldupont
10. November 2009 um 0:30 Uhr
@James Black: Das OP spricht offensichtlich über das Zeichenfolgenliteral
"hello world"
die tatsächlich im Nur-Lese-Speicher gespeichert werden können, unabhängig davon, wie der Zeiger deklariert ist.– AnT steht zu Russland
10. November 2009 um 0:36 Uhr
meine Referenz ist: stackoverflow.com/questions/1704407/…
– Benutzer188276
10. November 2009 um 0:40 Uhr
Ich bin auch neugierig, wenn wir eine Konstante deklarieren, z. B.: const int a; wird a auch in den Nur-Lese-Speicherbereich zugewiesen? (weil es konstant ist, nicht änderbar, also gehe ich davon aus)
– Benutzer188276
10. November 2009 um 0:41 Uhr