Segfault bei Pointerübergabe als Parameter
-
Hallo
Bin noch recht neu und versuche mich mal auf Pointern, habe aber ein Problem. Wenn ich das kompiliere und laufen lasse, kommt immer ein Segfault. kann mir jmd sagen, was ich falsch mache ?
#include <stdio.h> void my_test(int val, char* s); int main(void) { char* s; *s = 'i'; my_test(-2147, s); return 0; } void my_test(int val, char* s) { printf("Function call\n"); char* ptr = s; printf("%c\n", *ptr); }
Gruss Haudegen
-
s ist ein uninitialisierter Zeiger, er zeigt also irgendwo in den Speicher. Sobald du ihn dereferenzierst, hast du undefiniertes Verhalten.
-
Bei
char* s; *s = 'i';
liegt das Problem. Bei char* s bekommst du einfach einen Pointer, aber der zeigt auf nichts. Der zeigt ins Nirvana. Wenn du ihn nun mit *s dereferenzierst, dann moechtest du auf das Objekt zugreifen wo der Zeiger hinzeigt - aber da ist nichts. Das erzeugt undefiniertes Verhalten.
Du must den mit
char *s = new char;
initialisieren.
-
Hallo
Ah ok, wusste ich nicht, hätte gedacht der Pointer würde auf des erste Element im Speicher zeigen und dann weise ich den Charackter zu. Dann übergibt die Funktion die Adresse zum Charpointer.
Hab jetzt draus ein Array gemacht, kann ja dann das erste Element auch per Pointer ansteuern.
Vielen Dank, dachte schon ich sei dumm oder so
-
Haudegen9 schrieb:
Ah ok, wusste ich nicht, hätte gedacht der Pointer würde auf des erste Element im Speicher zeigen und dann weise ich den Charackter zu. Dann übergibt die Funktion die Adresse zum Charpointer.
Nein, du musst den Speicher explizit anfordern mit 'new'.
Haudegen9 schrieb:
Hab jetzt draus ein Array gemacht, kann ja dann das erste Element auch per Pointer ansteuern.
Wieso ein Array? Zeig mal den Code. Du brauchst doch gar kein Array? Hast du meine Loesung schon ausprobiert?
-
Hallo
Ich bins nochmals. Eine Frage hätte ich noch, wenn ich jetzt zB folgendes schreibe(C Code):
char* s = "h";
Dann wird der Pointer ja zugewiesen, ist es nun aber möglich, diesen String zu verlängern ?, also zB:
s++ *s = 'i' s++; *s = '\0';
So, dass schlussendlich "Hi\0" rauskommt ?
Gruss
-
Doppelt nein. Erstens zeigt s auf ein Zeichenkettenliteral. Dieses zu Ändern ist UB. In der Regel wird dies auch mit einem Absturz quittiert. Korrekter wäre daher eigentlich
const char* s = "h";
Zweitens würde die Aktion
s++ *s = 'i' s++; *s = '\0';
auch bei einer normalen Zeichenkette nicht zum Verlängern führen, sondern nur dazu, dass du hinter der Zeichenkette in irgendwelchen Speicher schreibst, der im Allgemeinen nicht zu der Zeichenkette gehört.
-
Wenn du die Stringspeichergröße dynamisch ändern willst, musst du dich in C mit malloc oder realloc rumschlagen.
Das von icarus2 vorgeschlagenenew
gibt es in C++.
-
Definiere dir ein deinen Anforderungen ausreichend großes char-Array und da kannst du dann beliebig rumändern, entweder mit dem Array selbst oder über einen Zeiger:
char a[1000]="H"; /* definiert einen 1000 Byte großen beschreibbaren Speicherbereich, füllt ihn mit '\0', das 0. Element mit 'H' */ /* wenn du a als String behandeln willst, darfst du bis a[998] rumändern, sonst bis a[999] */ char *ptr = a; puts(a); ++ptr; /* wenn du Zeiger üben willst; ++a ist natürlich nicht möglich, weil a ein unmodifizierbarer Lvalue ist */ *ptr='i'; puts(a); a[2]='i'; puts(a); usw.
-
DirkB schrieb:
Wenn du die Stringspeichergröße dynamisch ändern willst, musst du dich in C mit malloc oder realloc rumschlagen.
Das von icarus2 vorgeschlagenenew
gibt es in C++.Ach ja, tut mir Leid. Habe waehrend dem Schreiben vergessen, dass wir hier im C Forum sind
-
icarus2 schrieb:
Bei char* s bekommst du einfach einen Pointer, aber der zeigt auf nichts. Der zeigt ins Nirvana. Wenn du ihn nun mit *s dereferenzierst, dann moechtest du auf das Objekt zugreifen wo der Zeiger hinzeigt - aber da ist nichts. Das erzeugt undefiniertes Verhalten.
Das ist recht esoterisch formuliert. Ein Zeiger zeigt immer irgendwo hin, nämlich dort, was als Wert im Speicher steht. Die Frage ist, ob die Adresse gültig oder ungültig ist (evtl. Segmentation Fault). Wenn ja: Darf ich darauf zugreifen (evtl. Access violation)?
-
Deine Eigenart scheint zu sein, statt eindeutige Fragen zu stellen, erstmal mit deinem fundierten Halbwissen Behauptungen in den Raum zu stellen, in der Erwartung, dass jemand hier sich provoziert genug fühlt, darauf zu antworten und deine Behauptungen klarzustellen. (ich werde dies jedenfalls nicht mehr tun)
Nein, ein Zeiger zeigt nicht immer irgendwo hin, ein NULL Zeiger z.B. enthält als Wert (deine Wert-Formulierung ist auch falsch) eine 0 Integer-Konstante, und diese wird extrabehandelt.
Und nicht nur die Dereferenzierung von uninitialisierten Zeigern ist UB (deine Formulierungen access-violation,Seg.fault,ungültige/gültige Adresse sind auch alle keine standardkonformen Formulierungen) sondern gemäß ANSI C ist schon die Evaluierung, d.h. der Zugriff mittels Operator UB.
Und nein, ich werde dir jetzt nicht die verschiedenen Punkte aus dem Standard aufzählen, aus denen zusammengenommen, dies hervorgeht.
-
"Nirvana" und "nichts" sind sicherlich auch keine Begrifflichkeiten, die im Standard vorkommen. Ich hatte versucht das aus technischer Sicht zu schildern.
Fühlst dich aber verdammt schnell provoziert, obwohl ich dich nicht mal angesprochen hatte...L. G.
Steffo