Forum: Compiler & IDEs Zeiger als Rückgabewert, Fehler im Buch?


von Simon S. (-schumi-)


Lesenswert?

Hallo zusammen,

ich bin gerade hier: 
http://openbook.galileocomputing.de/c_von_a_bis_z/012_c_zeiger_006.htm#mj1d0c139ec6125f198a762880b480283f

Dort ist ein Beispiel für "Zeiger als Rückgabewert":
1
/* ptr13.c */
2
#include <stdio.h>
3
#include <stdlib.h>
4
#include <string.h>
5
#define MAX 255
6
7
char *eingabe(char *str) {
8
   char input[MAX];
9
10
   printf("Bitte \"%s\" eingeben: ",str);
11
   fgets(input, MAX, stdin);
12
   return strtok(input, "\n");
13
}
14
15
int main(void) {
16
   char *ptr;
17
18
   ptr = eingabe("Vorname");
19
   printf("Hallo %s\n", ptr);
20
   ptr = eingabe("Nachname");
21
   printf("%s, interssanter Nachname\n", ptr);
22
   return EXIT_SUCCESS;
23
}

Zudem schreibt der Autor:

> Folgendes funktioniert nicht:
1
char *eingabe(char *str) {
2
   char input[MAX];
3
4
   printf("Bitte \"%s\" eingeben: ", str);
5
   fgets(input, MAX, stdin);
6
   return input;                        // FEHLER
7
}

Warum ist mir klar: Der Speicherbereich in dem "input" liegt ist nachdem 
die Funktion verlassen wird wieder freigegeben. Es ist also nur eine 
Frage der Zeit, bis etwas anderes diesen Berreich überrschreibt.


Allerdings ist mir nicht ganz klar, warum dieser Fehler im ersten 
Codebeispiel nicht auftreten soll, desshalb habe ich mal einen Test 
gemacht:
1
/* ptr13.c */
2
#include <stdio.h>
3
#include <stdlib.h>
4
#include <string.h>
5
#define MAX 255
6
7
char *eingabe(char *str) {
8
   char input[MAX];
9
   printf("Bitte \"%s\" eingeben: ",str);
10
   fgets(input, MAX, stdin);
11
   printf("Adresse von input: %p\n", input);               // hier
12
   return strtok(input, "\n");
13
}
14
15
int main(void) {
16
   char *ptr;
17
   
18
   ptr = eingabe("Vorname");
19
   printf("Adresse von ptr: %p\n",ptr);                   // und hier
20
   printf("Hallo %s\n", ptr);
21
   ptr = eingabe("Nachname");
22
   printf("%s, interssanter Nachname\n", ptr);
23
   return EXIT_SUCCESS;
24
}

Lässt man das ganze laufen:
1
simon@simon-TravelMate-5735Z ~/Downloads/Listings/Kap012$ ./ptr13
2
Bitte "Vorname" eingeben: max
3
Adresse von input: 0x7fff8c20c4c0          # hier liegt "input" im Unterprogramm
4
Adresse von ptr: 0x7fff8c20c4c0            # die main liest aber aus diesem Berreich, obwohl der doch ungeschützt ist (?)
5
Hallo max
6
Bitte "Nachname" eingeben: mustermann
7
Adresse von input: 0x7fff8c20c4c0
8
musterma, interssanter Nachname            # hier hat anscheinend sogar schon etwas anderes eine NULL nach dem 'a' hingeschrieben...
Ich hätte vermutet, dass die strtok-Funktion ein eigenes static 
char-Arry anlegt, und der Adressbereich somit nicht mehr freigegeben 
wird (was wohl ziemlich ressourcenverschwendend wäre), aber man sieht ja 
dass der Pointer der gleiche bleibt, also die Funktion nichts eigenes 
anlegt..


Ist das Beispiel im Buch falsch? Oder versteh ich hier was nicht?

Viele Grüße
Simon

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Dein input[] liegt auf dem Stack, da gehört das nicht hin.
Wenn Du den Inhalt weiterverwenden willst, deklariere ihn als
static.

strtok() ist auch mit Vorsicht zu verwenden, es verändet den
ausgewertetn String.

von Ccccc (Gast)


Lesenswert?

Nicht alles Gedruckte ist richtig.
Lokale Variable sind nach return nicht mehr gültig.
Hat man ihre Adresse noch parat, dann kann die Variable (ein Teil) noch 
existiert, muß aber nicht.

von DirkB (Gast)


Lesenswert?

Du hast recht mit deiner Vermutung, Super erkannt. Glückunsch.
Das ist aber nicht der einzige Fehler in dem Buch.

strtok verändert den Eingabestring, indem es an Stelle der Trennzeichen 
ein '\0' schreibt.

von troll (Gast)


Lesenswert?

Investier ein paar € und besorg dir den K&R, es lohnt sich und der ist 
fehlerfrei.

von Simon S. (-schumi-)


Lesenswert?

Vielen Dank für eure Antworten :)

Na, dann ist ja jetzt alles klar. Ich glaube ich kann behaupten, Pointer 
verstanden zu haben^^

Den K&R werd ich mir wohl demnächst noch holen, scheint ja sehr gut zu 
sein.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

K&R haben mal C entwickelt. Verlaß Dich drauf, die kennen C ;)

von Yalu X. (yalu) (Moderator)


Lesenswert?

Leider ist die letzte Ausgabe K&R noch auf dem Stand von C89. Für C99
und erst recht für C11 braucht man zusätzliche Quellen. Trotzdem finde
ich das Buch gut, denn es ist vollständig, relativ dünn (<300 Seiten),
und dennoch ein richtiges Lehrbuch und nicht nur eine Sprachreferenz.

von (prx) A. K. (prx)


Lesenswert?

Yalu X. schrieb:
> Leider ist die letzte Ausgabe K&R noch auf dem Stand von C89.

Das wird sich mit diesen Autoren wohl auch nicht mehr ändern. Wär also 
die Frage, welches der Bücher über mindestens C99 empfehlenswert ist.

von (prx) A. K. (prx)


Lesenswert?

Joachim Drechsel schrieb:
> K&R haben mal C entwickelt. Verlaß Dich drauf, die kennen C ;)

Wikipedia: "Kernighan has said that he had no part in the design of the 
C language" - der hat am Buch mitgeschrieben, aber nicht am Design der 
Sprache. Das war Ritchie.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.