String-Literale: Wo gehen Sie hin?
Ich bin daran interessiert, wo string-Literale zugeordnet/gespeichert.
Fand ich eine faszinierende Antwort hier, nä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 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.
Sie müssen vorsichtig sein, über den buffer overflow bei Verwendung von arrays für veränderliche Zeichenketten, obwohl - einfach mit ein string länger als die array-Länge (z.B.
foo = "hello"
in diesem Fall) kann dazu führen, unerwünschten Nebenwirkungen... (vorausgesetzt, Sie sind nicht neu zuzuweisen, Speicher mitnew
oder so)Bei der Verwendung von array-string geht in stack oder anderswo ?
InformationsquelleAutor 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.)
movb $65, 8(%esp); movb $66, 9(%esp); movb $0, 10(%esp)
für die Zeichenfolge"AB"
, aber die überwiegende Mehrheit der Zeit, es werden in einem nicht-code-segment, wie.data
oder.rodata
oder ähnliches (je nachdem, ob oder nicht das Ziel unterstützt nur-lese-Segmente).Wenn string-Literale sind gültig für die gesamte Dauer des Programms, noch während die Vernichtung von statischen Objekten, dann ist es gültig-bis-return-const Referenz auf ein string-literal? Warum dieses Programm zeigt runtime error siehe ideone.com/FTs1Ig
InformationsquelleAutor 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 Ciro Santilli 新疆改造中心996ICU六四事件
FYI, nur das sichern der anderen Antworten:
Standard: ISO/IEC 14882:2003 sagt:
bestätigt #2 in 2.13. Mit -Os option (optimize for size), gcc überschneidungen string-Literale .rodata.
InformationsquelleAutor 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.
das ist, weil dieser Abschnitt nicht enthalten Montage. Es enthält Daten.
Nur eine Frage, um mehr lesbare Ausgabe. Ich meine, ich würde gerne strings inline mit Demontage statt der Adresse, um diese Abschnitte. (hem wissen Sie
printf("some null terminated static string");
stattprintf(*address);
in C)InformationsquelleAutor 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 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 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 mihai