Zeiger als Rückgabewert

Gast #647095
habe folgendes im buch Galileo Computing / C von A bis Z gefunden:

es geht um Zeiger als Rückgabewert:

SOLLTE Möglichkeit3 NICHT AUCH DATENMÜLL LIEFERN (gibt ja auch die 
Adresse einer lokalen Variablen zurück ) ?
1
/* ptr14.c */
2
#include <stdio.h>
3
#include <stdlib.h>
4
#include <string.h>
5
/* Fehler: Funktion gibt die Adresse
6
 * einer lokalen Variablen zurück */
7
char *test1(void){
8
   char buffer[10];
9
   strcpy(buffer, "testwert");
10
   return buffer;
11
}
12
/* Möglichkeit1: Statische Variable */
13
char *test2(void){
14
   static char buffer[10];
15
   strcpy(buffer, "testwert");
16
   return buffer;
17
}
18
/* Möglichkeit2: Speicher vom Heap verwenden */
19
char *test3(void){
20
   char *buffer = (char *) malloc(10);
21
   strcpy(buffer, "testwert");
22
   return buffer;
23
}
24
/* Möglichkeit3: Einen Zeiger als Argument übergeben */
25
char *test4(char *ptr){
26
   char buffer[10];
27
   ptr = buffer;
28
   strcpy(buffer, "testwert");
29
   return ptr;
30
}
31
int main(void) {
32
   char *ptr;
33
   ptr = test1();
34
   printf("test1: %s\n", ptr); // Datenmüll
35
   ptr = test2();
36
   printf("test2: %s\n", ptr);
37
   ptr = test3();
38
   printf("test3: %s\n", ptr);
39
   test4(ptr);
40
   printf("test4: %s\n", ptr);
41
   return EXIT_SUCCESS;
42
}
#647106
Was mich wundert:
Die vernünftigste Variante ist nicht erwähnt.

Möglichkeit 1: statische Variable.
  Das kann man machen, sollte man aber nicht ohne guten Grund
  machen. Das kann zu zunächst sehr seltsamen Effekten führen.

Möglichkeit 2: Speicher vom Heap
  Das problematische daran ist, dass der Aufrufer wissen muss,
  das der Speicher am Heap allokiert wurde und ihn wieder freigeben
  muss. Zb. im Test-main() passiert das nicht und ich werte das
  mal als bösen Fehler.

Möglichkeit 3:
  Wie du richtig erkannt hast, ist das genauso fehlerhaft, wie
  die allererste Variante

Bleibt noch Möglichkeit 4, die du am häufigsten antreffem wirst:
  Der Aufrufer muss den Speicher bereitstellen in den die Funktion
  die Daten hineinkopiert. Dabei sollte bei Arrays dann auch gleich
  noch die Grösse des Arrays mit übergeben werden, damit die Funktion
  prüfen kann, ob seine Daten in den bereitgestellten Speicherbereich
  passen.
1
char* test5(char *result, int maxLength)
2
{
3
   if( maxLength > 9 )
4
     strcpy(result, "testwert");
5
   return result;
6
}
7

8
int main(void) {
9
   char buffer[20];
10

11
   test5( buffer, sizeof(buffer) );
12
   printf("test5: %s\n", buffer);
13

14
   return EXIT_SUCCESS;
15
}
Gast #647138
Ich schätze, Möglichkeit 3 war ursprünglich als etwas ähnliches wie
Möglichkeit 4 von Karl heinz geplant gewesen (warum hätte sie sonst
überhaupt den Parameter ptr, der in der abgedruckten Variante gar
nicht genutzt wird), ist dann aber von einem ahnungslosen Mitautor
vollständig vermurkst worden.

<Klugscheißermodus>
>    if( maxLength > 9 )
8 hätte auch genügt, wenn maxLength die Größe des Arrays ist :)
</Klugscheißermodus>
Gast #647222
> SOLLTE Möglichkeit3 NICHT AUCH DATENMÜLL LIEFERN (gibt ja auch die
> Adresse einer lokalen Variablen zurück ) ?

Sie SOLLTE UNDEFINIERTES VERHALTEN LIEFERN. Das kann alles mögliche 
bedeuten. Letztendlich ist diese Variante sowieso ziemlich unsinnig. Der 
übergebene Zeigerwert wird überhaupt nicht benutzt.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 19 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.