Adreßrückgaben in C
Rückgabe von Adressen lokaler Variablen
Im folgenden Programm wird die Adresse der lokalen Variablen »i« der Funktion »f« zurückgegeben, die Lebensdauer jener Variablen »i« endet aber mit dem Ende der Inkarnation »f()«. Zu dem Zeitpunkt, zu welchem die Ausgabe in »main« erfolgt, existiert diese Variable schon nicht mehr. Daher darf auch ihre Adresse nicht mehr verwendet werden. Das Programm ist also fehlerhaft, obwohl es zufällig das vielleicht Erwartete ausgibt. (Es ist nicht garantiert, daß dieses eine Programm »9« ausgibt.)
main.c
#include <stdio.h>
int * f( void ){ int i = 9; return &i; }
int main( void ){ printf( "%d\n", *f() ); }
Compile Log
main.c: In function 'f':
main.c:2:23: warning: function returns address of local variable [-Wreturn-local-addr]
int * f(){ int i = 9; return &i; }
^stdout
9
Die Adresse einer lokalen Variablen sollte nicht zurückgegeben werden!
Man beachte die Form in welcher oben der Rückgabetyp von »f« mit »int *« deklariert wird.
Rückgabe von Parameterwerten
Es ist aber nicht immer fehlerhaft, eine Adresse zurückzugeben.
Falls das Objekt der Adresse die Inkarnation einer Funktion überdauert, kann die Rückgabe der Adresse erlaubt sein. Dies zeigt das folgende Beispielprogramm.
main.c
#include <stdio.h>
int * f( int * const p ){ return p; }
int main( void )
{ int i = 3;
printf( "%d\n", *f( &i ) ); }stdout
3
Die Funktion »f« gibt oben in »f( &i )« die Adresse des Objektes »i« zurück. Da dieses Objekt bis zum Ende des Ablaufs der Funktion »main« existiert, darf der Wert von »f( &i )« verwendet und dereferenziert werden.
Später werden wir Situationen kennenlernen, in denen die Rückgabe einer Adresse sinnvoll ist.
Beispiel
Das folgende Programm zeigt, daß – unter der verwendeten Implementation – die linke Seite einer Zuweisung in dem folgenden Beispiel zuerst ausgewertet wird.
main.c
#include <stdio.h>
int * f( int * const p ){ puts( "f" ); return p; }
int g(){ puts( "g" ); return 1; }int main()
{ int n = 0;
*f( &n )= g(); }transcript
f
g