e.full Geschrieben 19. November 2008 Geschrieben 19. November 2008 hallo habe ne frage; also wieso erwartet die funktion scanf Zeiger auf die einzulesenden Daten, und wieso nimmt die Funktion printf die auszugebenden daten direkt entgegen. Zitieren
Gooose Geschrieben 20. November 2008 Geschrieben 20. November 2008 Beispiel: #include <stdio.h> int main() { int* i; scanf("%d",&i); printf("%d",i); return 0; } int* i ist vom Typ Zeiger auf Int. Das heißt, daß was an der Speicherstelle von i steht kann einen Integer Wert aufnehmen. Bei 32 Bit Systemen werden hier 4 Byte für den Pointer reserviert. scanf hat "const char* format" und weitere Argumente. In diesem Fall die Adresse von dem Zeiger, der auf einen Integer Wert zeigt. D.h. der Funktion wird mitgeteilt, an welche Speicherstelle sie die Eingabe speichern soll. In diesem Fall erwartet die Funktion als Eingabe einen Integer Wert. Zwischenbeispiel: int i = 5; int* pi = &i; Hier zeigt pi auf die Adresse von i. Noch eine Anmerkung zu "const char* format": In C gibt es keine Strings. Ein Stringliteral wie z.b. "Hallo Welt" wird als array of char bezeichnet. man könnte sagen: char* s = "Hallo Welt"; hierbei Zeigt der Zeiger auf das erste Element des Stringliterals. Generell schau mal unter: Galileo Computing :: C von A bis Z – 5 Formatierte Eingabe mit scanf() Bleib am Ball. Zitieren
Klotzkopp Geschrieben 20. November 2008 Geschrieben 20. November 2008 In C werden Funktionsparameter "by value" übergeben, d.h. die Funktion bekommt eine Kopie des Wertes, der beim Aufruf übergeben wurde (Ausnahme: Arrays). Änderungen an dieser Kopie ändern natürlich nichts an der Originalvariablen. Damit eine Funktion wie scanf also überhaupt etwas tun kann, muss ein Verweis übergeben werden, über den die Originalvariable erreichbar ist. Und die einzige Möglichkeit in C, das zu tun, ist ein Zeiger. Zitieren
Guybrush Threepwood Geschrieben 20. November 2008 Geschrieben 20. November 2008 Der erste Beispielcode ist falsch weil i ein uninitialisierter Zeiger ist. Das funktioniert nur zufällig weil da ein Pointer genau so groß wie int ist. Zitieren
Gooose Geschrieben 20. November 2008 Geschrieben 20. November 2008 Oh, da hast du recht. Mein Fehler. Zitieren
e.full Geschrieben 20. November 2008 Autor Geschrieben 20. November 2008 hmm ok danke, und warum nimmt die funktion printf die auszugebenden daten direkt entgegen??? jetzt im allgemeinen fall Zitieren
Klotzkopp Geschrieben 20. November 2008 Geschrieben 20. November 2008 und warum nimmt die funktion printf die auszugebenden daten direkt entgegen???Weil sie sie nicht verändern muss. Zitieren
e.full Geschrieben 20. November 2008 Autor Geschrieben 20. November 2008 hmm ok danke, habe noch eine frage: ich habe ein ausschnitt aus einem c-programm: 01 char *str1, *str4 = 0; 02 char str2 [] = "t2"; 03 char *str3 [2] = {" Element_0" , "Element_1" }; 04 str1 = malloc (5); 05 str3 [0] = str1; 06 strcpy ( str1, "test1"); 07 strcpy (str1, str2); 08 strcpy (str3[0], "test3"); 09 strcpy (str4, str2); also ich soll jetzt die programmzeilen nennen, in denen auf ungültige speicher zugegriffen wird, und genau beschreiben, weshalb die zugriffe unzulässig sind. nur ich weiss jetzt nicht wie ich das merke, gibt es da bestimmte regel oder so würde mich auf eine antwort freuen, da ich erst neu anfange zu programmieren und nicht weiss wie das so funktioniert. Zitieren
Klotzkopp Geschrieben 20. November 2008 Geschrieben 20. November 2008 Folgende Operationen sind verboten, weil sie undefiniertes Verhalten erzeugen: Jegliche Zugriffe über uninitialisierte ZeigerJegliche Zugriffe über NullzeigerSchreibzugriffe auf StringliteraleJegliche Zugriffe über den alloziierten Speicherbereich hinaus (Buffer Overflow) Zitieren
e.full Geschrieben 20. November 2008 Autor Geschrieben 20. November 2008 hmm, und wie könnte ich das auf den obrigen abschnitt anwenden. Zitieren
Klotzkopp Geschrieben 20. November 2008 Geschrieben 20. November 2008 Schreib auf, wohin die einzelnen Zeiger zeigen, also unintialisiert, NULL, Literal (mit Größe) oder gültiger Speicher (mit Größe), und prüfe Zeile für Zeile, was die Anweisungen tun. Beispiel : Zeile 1: str1 ist uninitialisiert, str4 ist NULL Zeile 2: str2 ist ein Array auf dem Stack, Größe 3 usw. Zitieren
e.full Geschrieben 20. November 2008 Autor Geschrieben 20. November 2008 also ich habe da mal was versucht, aber weiss net ob es richtig ist: also ab zeile 3: 03 str3 ist ein Array und ist gleichzeitig Element von 0 und 1 04 str1 reserviert einen Speicherplatz 05 str3 ist ein Array und gleichzeitig str1 06 str1 kopiert eine Zeichenkette zu test1 07 str1 und str2 kopieren zeichenketten 08 str3 ist ein Nullelement 09 str4 kopiert eine zeichenkezze zu str 2 Zitieren
Klotzkopp Geschrieben 20. November 2008 Geschrieben 20. November 2008 Du musst da schon ein wenig genauer arbeiten: 03 str3 ist ein Array und ist gleichzeitig Element von 0 und 1str3 ist ein Array von 2 Zeigern, str3[0] und str3[1]. str3[0] zeigt auf ein Literal der Länge 11, str3[1] auf ein Literal der Länge 10. 04 str1 reserviert einen Speicherplatzstr1 zeigt auf gültigen Speicher der Länge 5. 05 str3 ist ein Array und gleichzeitig str1 str3[0] zeigt nicht mehr auf Literal, sondern auf denselben gültigen Speicherbereich wie str1. usw. Zitieren
e.full Geschrieben 20. November 2008 Autor Geschrieben 20. November 2008 okii, aber bei strcpy war ich mir gar nicht sicher und weiss irgendwie auch nicht wie ich das audführlich bearbeiten soll :-( Zitieren
Klotzkopp Geschrieben 20. November 2008 Geschrieben 20. November 2008 Was genau ist denn unklar? Wenn ich dir noch mehr Beispiele gebe, kann ich dir ja auch gleich die Komplettlösung vorsetzen. Zitieren
e.full Geschrieben 20. November 2008 Autor Geschrieben 20. November 2008 ne ich weiss jetzt irgendwie noch nicht welche zeilen auf ungültige speicher zugreifen Zitieren
Klotzkopp Geschrieben 20. November 2008 Geschrieben 20. November 2008 ne ich weiss jetzt irgendwie noch nicht welche zeilen auf ungültige speicher zugreifen Kannst du bitte auf das Wort "irgendwie" verzichten? Du kannst nicht "wissen", welche Zeilen ungültig sind, ohne genau herauszuarbeiten, welcher Zeiger wohin zeigt, und was wohin kopiert wird. Wenn du das "irgendwie" nicht kannst, können wir dir hier auch nicht helfen. Du musst schon konkret erklären, womit du Probleme hast. Zitieren
e.full Geschrieben 20. November 2008 Autor Geschrieben 20. November 2008 ja also ich muss ja zunächst schreiben wo die zeiger hin zeigen. bei strcpy weiss ich jetzt noch nicht genau wo die zeiger hin zeigen, ich weiss das die funktion strcpy eine zeichenkette kopiert. jetzt in den zeilen von 06-09 06 es wird eine Zeichenkette von str1 in test1 kopiert 07 str1 kopiert ihre zeichenkette in str2 08 str3 kopiert ihr Nullelement in test3 09 str4 kopiert ihre zeichenkette in str 2 ich weiss jetzt nicht wie ich das anders beschreiben soll Zitieren
Klotzkopp Geschrieben 20. November 2008 Geschrieben 20. November 2008 bei strcpy weiss ich jetzt noch nicht genau wo die zeiger hin zeigen,strcpy ändert nichts daran, wo die Zeiger hinzeigen. 06 es wird eine Zeichenkette von str1 in test1 kopiertNein, der erste Parameter von strcpy ist das Ziel, der zweite ist die Quelle. Bei strcpy musst du prüfen: ob der Quellzeiger auf Speicher zeigt, aus dem gelesen werden darf,ob dieser Speicher einen terminierten String enhält,ob das Ziel auf Speicher zeigt, in den geschrieben werden darf, undob dieser Speicher groß genug für den String (mit Terminierung) ist. Mach das mal für Zeile 6. Zitieren
e.full Geschrieben 20. November 2008 Autor Geschrieben 20. November 2008 also 06 str1 zeigt auf speicher test 1, indem geschrieben werden darf Zitieren
Klotzkopp Geschrieben 20. November 2008 Geschrieben 20. November 2008 06 str1 zeigt auf speicher test 1, indem geschrieben werden darf Ich sagte doch, dass strcpy nichts daran ändert, wohin die Zeiger zeigen. Quelle und Ziel zeigen dahin, wo sie vorher auch hingezeigt haben. Du sollst die vier Dinge prüfen, die ich da hingeschrieben habe. Das kannst du nicht in einem Satz abhandeln. Zitieren
e.full Geschrieben 20. November 2008 Autor Geschrieben 20. November 2008 06: dieser speicher enthält einen terminierten string der ziel zeigt auch auf den speicher, in den geschrieben werden darf und speicher ist groß genug Zitieren
Klotzkopp Geschrieben 20. November 2008 Geschrieben 20. November 2008 dieser speicher enthält einen terminierten string der ziel zeigt auch auf den speicher, in den geschrieben werden darf und speicher ist groß genugNicht ganz. Die Quelle ist "test1", das ist ein Literal der Länge 6, denn die Terminierung muss man mitzählen. Die wird von strcpy auch mit kopiert. Die Quelle ist also soweit in Ordnung. In das Ziel darf auch geschrieben werden, aber nur 5 Bytes. Dies ist also die erste Zeile mit ungültigem Zugriff. Zitieren
e.full Geschrieben 20. November 2008 Autor Geschrieben 20. November 2008 ok, jetzt mit 07: also ich denke das hier die 4 bedingungen erfüllt sind, und der zugriff gültig ist Zitieren
Klotzkopp Geschrieben 20. November 2008 Geschrieben 20. November 2008 also ich denke das hier die 4 bedingungen erfüllt sind, und der zugriff gültig istWenn du das nicht begründest, kann ich nicht sagen, ob du hier richtig gedacht hast, aber das Ergebnis stimmt. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.