String-Literale: Wohin gehen sie?
Ich bin daran interessiert, wo string-Literale zugeordnet/gespeichert.
Fand ich eine faszinierende Antwort hiernämlich:
Definition einer string-inline tatsächlich bettet die Daten in das Programm selbst und kann nicht geändert werden (einige Compiler dies zulassen, von einem klugen trick, nicht stören).
Aber, es hatte zu tun mit C++, nicht zu erwähnen, dass es sagt, nicht zu stören.
Ich mich damit befasse. =D
Also meine Frage ist, wo und wie ist mein string-literal gespeichert? Warum sollte ich nicht versuchen, zu ändern? Auch die Umsetzung variieren von Plattform zu Plattform? Hat jemand die Pflege zu erarbeiten, die "smart trick?"
InformationsquelleAutor der Frage Chris Cooper | 2010-04-07
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ist eine verbreitete Technik, ist für string-Literale sind in "nur-Lesen-Daten" - Abschnitt, wird der im Prozess abgebildeten Raum als read-only (das ist, warum Sie können es nicht ändern).
Es variiert von Plattform zu Plattform. Zum Beispiel, einfacher chip-Architekturen unterstützt möglicherweise nicht die nur-lese-Speicher-Segmenten, so dass die Daten-segment wird schreibgeschützt sein.
Dann eher versuchen, herauszufinden, einen trick, um string-Literale änderbar (es ist in hohem Grade abhängig von Ihrer Plattform und konnten im Laufe der Zeit ändern), benutzen Sie einfach arrays:
Den compiler veranlassen, das der array zu erhalten, initialisiert von der wörtlichen, und ändern Sie das array.
InformationsquelleAutor der Antwort R Samuel Klatchko
Gibt es keine Antwort auf diese Frage. Die C-und C++ - standards nur sagen, dass die string-Literale haben static storage duration, jeder Versuch Sie zu ändern, gibt Undefiniertes Verhalten, und mehrere string-Literale mit dem gleichen Inhalt kann oder kann nicht den gleichen Speicher.
Je nach system sind Sie für das schreiben und die Möglichkeiten der ausführbaren Datei-format verwendet, können Sie gespeichert werden, zusammen mit dem Programm-code im text-segment, oder Sie können ein eigenes segment für initialisierte Daten.
Bestimmung der details variieren je nach der Plattform als gut-die meisten wahrscheinlich gehören tools, die Ihnen sagen kann, wo es ist, es zu setzen. Einige werden sogar geben Ihnen die Kontrolle über details wie, dass, wenn Sie es wollen (z.B. gnu-ld können Sie liefern ein Skript zu sagen, alles darüber, wie Sie zum gruppieren von Daten, code, etc.)
InformationsquelleAutor der Antwort Jerry Coffin
Warum sollte ich nicht versuchen, zu ändern?
Weil es zu undefiniertem Verhalten. Zitat von C99 N1256 Entwurf 6.7.8/32 "Initialisierung":
Wo gehen Sie hin?
GCC 4.8 x86-64, ELF-Ubuntu 14.04:
char s[]
: stackchar *s
:.rodata
Abschnitt der Objektdatei.text
Abschnitt der Objektdatei wird gestürzt, mit dem Sie Lese-und Exec-Berechtigungen, aber nicht SchreibenProgramm:
Kompilieren und dekompilieren:
Ausgabe enthält:
Also die Zeichenfolge gespeichert wird in der
.rodata
Abschnitt.Dann:
Enthält (vereinfacht):
Dies bedeutet, dass das default linker-script-dumps beide
.text
und.rodata
in einem segment, die ausgeführt werden können, aber nicht geändert werden (Flags = R E
). Versuch, ändern solche-segment führt zu einem segmentation Fault unter Linux.Wenn wir das gleiche tun für
char[]
:erhalten wir:
also es wird auf dem stack gespeichert (im Verhältnis zu
%rbp
), und natürlich können wir es ändern.InformationsquelleAutor der Antwort Ciro Santilli 新疆改造中心 六四事件 法轮功
FYI, nur das sichern der anderen Antworten:
Standard: ISO/IEC 14882:2003 sagt:
InformationsquelleAutor der Antwort Justicle
gcc macht einen
.rodata
Abschnitt, der abgebildet werden "irgendwo" im Adressraum und ist als schreibgeschützt markiert,Visual C++ (
cl.exe
) macht eine.rdata
Abschnitt für den gleichen Zweck.Kann man sich die Ausgabe von
dumpbin
oderobjdump
(auf Linux), um die Abschnitte in die ausführbare Datei.E. g.
InformationsquelleAutor der Antwort Alex Budovski
Hängt es von der format Ihrer ausführbare. Eine Art, nachzudenken ist, dass, wenn Sie waren, assembly programming, können Sie string-Literale im Daten-segment des Assembler-Programm. Der C-compiler tut so etwas, aber es hängt alles davon ab, welches system Sie sind binary kompiliert wird.
InformationsquelleAutor der Antwort Parappa
String-Literale sind Häufig zugewiesen, um die nur-lese-Speicher, so dass Sie unveränderlich sind. Jedoch, in einigen Compilern änderung ist möglich durch ein "schlauer trick"..Und die smart trick ist, durch "die Verwendung von Zeichen-Zeiger auf Speicher"..erinnere mich an einige Compiler können nicht zulassen, dass dies..Hier ist demo
InformationsquelleAutor der Antwort Sahil Jain
Als diese könnten sich von compiler zu compiler, der beste Weg ist, zum filtern von ein-Objekt-dump für die gesuchte string-literal:
wo
-s
Kräfteobjdump
zum anzeigen des vollständigen Inhalte aller Abschnittemain.o
ist die Objekt-Datei-B 1
Kräftegrep
zu drucken eine Zeile vor dem match (so dass Sie sehen können, den Namen des Abschnitts) und diestr
ist das string-literal, die Sie suchen.Mit gcc auf einem Windows-Rechner, und eine variable deklariert, in
main
wieläuft
gibt
InformationsquelleAutor der Antwort mihai