Segmentierungsfehler mit Char Array und Zeiger in C unter Linux

Lesezeit: 2 Minuten

Also ich habe folgendes Programm:

int main(){
  char* one = "computer";
  char two[] = "another";
  two[1]='b';
  one[1]='b';
  return 0;
}

Es segfaults auf der Zeile “one .”[1]=’b'”, was sinnvoll ist, da der Speicher, auf den der Zeiger “one” zeigt, im Nur-Lese-Speicher sein muss. Die Frage ist jedoch, warum die Zeile “two[1]=’b'” segfault? Betrachten Sie die Assembly-Ausgabe von gcc:

.file   "one.c"
        .section        .rodata
.LC0:
        .string "computer"
.LC1:
        .string "another"
        .text
.globl main
        .type   main, @function
main:

Wir sehen, dass sich beide Strings im Rodata-Abschnitt befinden und somit schreibgeschützt sind. Wie kommt es dann zu der Zeile “zwei[1]=’b’ führt keinen Segfault aus?

  • Siehe auch die andere, aber verwandte Frage stackoverflow.com/questions/177062/…

    – Pascal Cuoq

    20. November ’09 um 20:43

Segmentierungsfehler mit Char Array und Zeiger in C unter
mmx

one zeigt direkt auf die Zeichenfolge, die sich auf einer schreibgeschützten Seite befindet. Auf der anderen Seite, two ist ein Array, das auf dem Stack zugewiesen ist und mit einigen konstanten Daten initialisiert wird. Zur Laufzeit wird die Zeichenfolge im schreibgeschützten Abschnitt der ausführbaren Datei auf den Stack kopiert. Was Sie ändern, ist die Kopie dieser Zeichenfolge auf dem Stack, nicht die schreibgeschützte Speicherseite.

Auf einer höheren Ebene, aus sprachlicher Sicht, "abcd" ist ein Ausdruck von Typ const char* und nicht char*. Daher führt das Ändern des Werts, auf den ein solcher Ausdruck zeigt, zu undefiniertem Verhalten. Die Aussage char* one = "something"; speichert lediglich den Zeiger auf den String in einer Variablen (unsicher, da er weggeworfen wird) const Modifikator). Der char two[] = "something"; ist ganz anders. Es deklariert tatsächlich ein Array und initialisiert es, ähnlich wie int a[] = {1,2,3};. Die Zeichenfolge in Anführungszeichen ist hier der Initialisierungsausdruck.

  • Wow… ich programmiere jetzt seit ca. 5 Jahren in C und war mir dessen nicht bewusst char[] eine Kopie der konstanten Daten erstellt. Ich dachte immer [] war nur eine schickere Art zu schreiben *. Danke schön! +1

    – Earlz

    20. November ’09 um 20:39 Uhr

  • ich schreibe oft char str[] = {"Something"}; um die Assoziation zu verdeutlichen.

    – LnxPrgr3

    20. Nov. 09 um 21:01

Segmentierungsfehler mit Char Array und Zeiger in C unter
Remo.D

Das “andere”, das Sie im Rodata-Abschnitt sehen, wird in das Array kopiert two wann es initialisiert wird. Auf der anderen Seite die die Anschrift der Zeichenfolge “Computer” wird einem zugewiesen.

So, one zeigt auf ein Nur-Lese-Segment (und damit auf den Segfault beim Schreiben) während two wird auf dem Stack zugewiesen und dann wird “ein anderer” hineinkopiert.

Die zweite Form erstellt ein Array durch Kopieren der Literalzeichenfolge.

Es ist äquivalent zu:

char two[] = {'a', 'n', 'o', 't', 'h'. 'e', r', ''};

Sie können ein Zeichenarray mit Variablen initialisieren, wie z

char c="a";
char two[] = {'a', 'n', c, ''};

.

481380cookie-checkSegmentierungsfehler mit Char Array und Zeiger in C unter Linux

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy