Zeiger als Rückgabewert, Fehler im Buch?

#3131975
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
Gast #3132246
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.
Moderator #3133343
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren