char* übergeben und modifiziert => Zugriffsverletzung???
-
Hallo.
Beim folgenden Programm bekomme ich einen Ausnahmefehler.
Was ist das Problem und wie kann ich es richtig machen?
Am Ende soll das Programm '193' ausgeben.#include <stdio.h> #include <string.h> void ModifyString(char* pString) { int len = strlen(pString); // len=3 pString[1] = '9'; // Fehler!!! } int main() { char* pString = "123"; ModifyString(pString); printf(pString); }
-
Stringliterale (also "123") sind typischerweise read-only.
-
so sollte es gehen
#include <stdio.h> #include <string.h> #include <windows.h> void ModifyString(char* pString) { unsigned long old; VirtualProtect((LPVOID)pString, 1024, PAGE_READWRITE, &old); int len = strlen(pString); // len=3 pString[1] = '9'; // Fehler!!! } int main() { char* pString = "123"; ModifyString(pString); printf(pString); }
-
#include <stdio.h> #include <string.h> void ModifyString(char* pString) { int len = strlen(pString); // len=3 pString[1] = '9'; // Fehler!!! } int main() { char pString[] = "123"; ModifyString(pString); printf("%s", pString); }
-
Was ist denn der Unterschied zwischen
char* pString = "123";
und
char pString[] = "123";
???
-
das eine ist ein schreibgeschütztes stringliteral, das andere ist ein schreibbares char array auf dem stack.
-
Bei ersterem hast du einen Zeiger der auf ein Literal zeigt.
Bei letzterem hast du ein Array welches mit einem Literal initialisiert wird. Hier kannst du den Inhalt des Arrays modifizieren.
-
Danke schön für eure Antworten, ich denke ich hab's verstanden.
-
wollens hoffen.
mfg.
-
Eine Frage noch:
Was ist der entscheidende Unterschied zwischen diesen beiden Funktionsdeklarationen?
int foo_x (char* buffer);
int foo_y (char buffer[256]);
-
version nummer eins erwartet einen zeiger auf char. dahinter kann ein zeichen oder ganz viele zeichen folgen. auf dem stack wird sizeof(char*) byte angelegt (erkennbar an der symmetrischen schneeflocke: *), die Adresse wird in buffer reinkopiert.
version nummer zwei erwartet ein chararray mit 256 elementen, es werden 256*sizeof(char) byte auf dem stack angelegt und es werden 256 übergebene elemente kopiert.
-
klar0r schrieb:
version nummer zwei erwartet ein chararray mit 256 elementen, es werden 256*sizeof(char) byte auf dem stack angelegt und es werden 256 übergebene elemente kopiert.
nein, sie sind an sich identisch, in version 2 ist buffer auch nur ein char* Zeiger.
void ver1(char *a) { printf("sizeof a = %d\n", sizeof a); } void ver2(char a[64]) { printf("sizeof a = %d, a[99] = %c\n", sizeof a, a[99]); } int main(void) { char c[100]; c[99] = 'A'; ver1(c); ver2(c); return 0; }
erzeugt
sizeof a = 4 sizeof a = 4, a[99] = A
und bei
void ver1(char *a) { printf("sizeof a = %d\n", sizeof a); } void ver2(char a[64]) { printf("sizeof a = %d\n", sizeof a); }
sieht der Assembler Code (gcc, x86) so aus:
080483d0 <ver1>: 80483d0: 55 push %ebp 80483d1: 89 e5 mov %esp,%ebp 80483d3: 83 ec 08 sub $0x8,%esp 80483d6: c7 44 24 04 04 00 00 movl $0x4,0x4(%esp) 80483dd: 00 80483de: c7 04 24 0c 85 04 08 movl $0x804850c,(%esp) 80483e5: e8 16 ff ff ff call 8048300 <printf@plt> 80483ea: c9 leave 80483eb: c3 ret 080483ec <ver2>: 80483ec: 55 push %ebp 80483ed: 89 e5 mov %esp,%ebp 80483ef: 83 ec 08 sub $0x8,%esp 80483f2: c7 44 24 04 04 00 00 movl $0x4,0x4(%esp) 80483f9: 00 80483fa: c7 04 24 0c 85 04 08 movl $0x804850c,(%esp) 8048401: e8 fa fe ff ff call 8048300 <printf@plt> 8048406: c9 leave 8048407: c3 ret
-
das ist ja der hamm0r!
ich war fest davon überzeugt, das 256 kopien angelegt würden!
ok, bin ich nun wieder etwas schlau0r!gruß,
k.
-
und: @supertux, vielen dank für den post!
gruß,
klar0r
-
Das heißt, die Zahl wird eigentlich ignoriert?
-
KomischerName schrieb:
Das heißt, die Zahl wird eigentlich ignoriert?
welche Zahl meinst du?
-
die 256 in der deklaration
int foo_y (char buffer[256]);
-
ja, so könnte man es sagen, wobei bei
func(datatype var[xxx])
istvar
kein Array sondern ein Zeiger, ein großer Unterschied.
-
gilt das eigentlich für alle datentypen, also auch für strukturen und so?
-
ja.