Was ich nicht verstehe ist, warum der zweite Test fehlschlägt? Für mich sieht es aus wie die erste Notation char *ptr = "string"; ist äquivalent zu diesem: char ptr[] = "string";.
Lesen Sie: Unterschied zwischen char *str und char str[] und wie speichert beides im Gedächtnis?
– Grijesh Chauhan
6. September 2013 um 5:36 Uhr
codaddict
Die beiden Deklarationen sind nicht identisch.
char ptr[] = "string"; deklariert ein char-Array der Größe 7 und initialisiert es mit den Zeichen s ,t,r,i,n,g und \0. Sie sind erlaubt um den Inhalt dieses Arrays zu ändern.
char *ptr = "string"; erklärt ptr als Zeichenzeiger und initialisiert ihn mit der Adresse von String-Literal"string" welches ist schreibgeschützt. Das Ändern eines Zeichenfolgenliterals ist eine undefiniertes Verhalten. Was Sie gesehen haben (seg fault) ist eine Manifestation des undefinierten Verhaltens.
Und ein sizeof(ptr) liefert auch unterschiedliche Ergebnisse für die verschiedenen Deklarationen. Der erste gibt die Länge des Arrays einschließlich des abschließenden Nullzeichens zurück. Die zweite gibt die Länge eines Zeigers zurück, normalerweise 4 oder 8.
– Prof. Falken
5. Oktober 2010 um 12:53 Uhr
Es gilt zweitens auch, dass der Inhalt von ptr verändert werden kann. Aber der Inhalt ist der Zeiger auf das Literal, nicht die Zeichen.
– Daron
5. Oktober 2010 um 13:10 Uhr
+1, tolle Antwort. Es ist auch wahr und wichtig, das mit zu verstehen char *ptr = "string"; das ptr kann auf etwas anderes zeigen und kann daher in dem, worauf es zeigt, außer den Zeichen “geändert” werden "string" ist ein Literal und kann sich nicht ändern.
– Kumpel
5. Oktober 2010 um 16:07 Uhr
Erwähnenswert wären auch die Performance-Probleme. Das Deklarieren einer initialisierten automatischen Array-Variablen füllt den gesamten Array-Inhalt jedes Mal, wenn die Variable in den Geltungsbereich kommt. Durch das Deklarieren einer initialisierten automatischen Zeigervariablen wird einfach der Zeiger zugewiesen (ein einzelnes Wort schreiben), wenn die Variable in den Gültigkeitsbereich kommt. Wenn die Zeichenfolge lang ist oder der Block häufig eingegeben wird (wie bei jeder Iteration einer Schleife), kann der Unterschied sehr signifikant sein!
– R.. GitHub HÖR AUF, EIS ZU HELFEN
6. Oktober 2010 um 6:27 Uhr
@AmigableClarkKant, eigentlich, sizeof(ptr) ist nicht die Länge des Arrays, es sei denn ptr wird als char-Array deklariert. Wenn ptr ist definiert als ein int Array mit 3 Elementen, sizeof(ptr) wird die Summe von zurückgeben sizeof(int) jedes Elements.
– 爱国者
24. Januar 2012 um 8:20 Uhr
Genau genommen eine Erklärung von char *ptr garantiert Ihnen nur einen Zeiger auf den Zeichentyp. Es ist nicht ungewöhnlich, dass die Zeichenfolge einen Teil des Codesegments der kompilierten Anwendung bildet, die von einigen Betriebssystemen auf schreibgeschützt gesetzt wird. Das Problem liegt in der Tatsache, dass Sie eine Annahme über die Art der vordefinierten Zeichenfolge treffen (dass sie beschreibbar ist), obwohl Sie tatsächlich nie selbst explizit Speicher für diese Zeichenfolge erstellt haben. Es ist möglich, dass einige Implementierungen von Compiler und Betriebssystem es Ihnen ermöglichen, das zu tun, was Sie versucht haben.
Auf der anderen Seite die Erklärung von char test[]weist in diesem Fall per Definition lesbaren und beschreibbaren Speicher für das gesamte Array von Zeichen auf dem Stapel zu.
So weit ich mich erinnere
char ptr[] = "string";
schafft ein Kopieren von "string" auf dem Stapel, also ist dieser veränderlich.
Die Form
char *ptr = "string";
ist nur Abwärtskompatibilität für
const char *ptr = "string";
und Sie dürfen (in Bezug auf undefiniertes Verhalten) seinen Inhalt nicht ändern. Der Compiler kann solche Strings in einem Nur-Lese-Abschnitt des Speichers platzieren.
char *test = "string test"; ist falsch, hätte es sein sollen const char*. Dieser Code wird nur aus Gründen der Abwärtskompatibilität kompiliert. Die Erinnerung wies darauf hin const char* ist ein Nur-Lese-Speicher und wenn Sie versuchen, darauf zu schreiben, wird er ein undefiniertes Verhalten hervorrufen. Auf der anderen Seite char test[] = "string test" schafft ein schreibbar Zeichenarray auf Stapel. Dies ist wie jede andere reguläre lokale Variable, in die Sie schreiben können.
Gute Antwort @codaddict.
Auch eine sizeof(ptr) wird für die verschiedenen Deklarationen unterschiedliche Ergebnisse liefern.
Die erste, die Array-Deklaration, gibt die Länge des Arrays zurück einschließlich das abschließende Nullzeichen.
Der zweite, char* ptr = "a long text..."; gibt die Länge eines Zeigers zurück, normalerweise 4 oder 8.
Ravi Chandra
char *str = strdup("test");
str[0] = 'r';
ist richtiger Code und erstellt eine veränderliche Zeichenfolge. str wird ein Speicher im Heap zugewiesen, der Wert ‘test’ wird darin ausgefüllt.
13693000cookie-checkUnterschied zwischen char *str=”STRING” und char str[] = “ZEICHENFOLGE”?yes
Sehr guter Artikel zu diesem Thema: eli.thegreenplace.net/2009/10/21/…
– jyz
10. April 2013 um 17:03 Uhr
Lesen Sie: Unterschied zwischen
char *str
undchar str[]
und wie speichert beides im Gedächtnis?– Grijesh Chauhan
6. September 2013 um 5:36 Uhr