"We are back" « oc.at

[C] return - zeiger

lama007 08.02.2009 - 19:31 6767 52 Thread rating
Posts

lama007

OC Addicted
Avatar
Registered: Mar 2002
Location: Austria
Posts: 851
Hi,

ich gebs zu, das Beispiel ist nicht besonders sinnvoll.
Aber warum soll man so etwas "return( &c )" nicht machen?

Code:
#include <stdio.h>

int *plus( int x, int y );

int main( void )
  { 	
  int a = 2, b = 3;
  printf( "%d\n", *plus( a, b ) );
  return( 0 );
  }

int *plus( int x, int y )
  {
  int c; 	
  c = x + y;
  return( &c );
  } 

Timmää

Big d00d
Avatar
Registered: Nov 2007
Location: linz
Posts: 222
weil du die adresse von c zurückgibst
die variable c aber lokal deklariert ist und daher außerhalb der funktion nicht verfügbar ist

bin mir nicht sicher aber denke mal es ist so
google mal scope und duration
Bearbeitet von Timmää am 08.02.2009, 19:44

semteX

begehrt die rostschaufel
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14701
exakt das isses.

DirtyHarry

aka robobimbo
Avatar
Registered: Apr 2001
Location: outer space
Posts: 464
was timmää sagt stimmt schon, die gültigkeit von der variable c endet mit dem return.

das heisst du bekommst einen zeiger zurück der auf das stacknirvana zeigt. das kann zufällig noch die richtige variable, kann aber auch totaler datenmüll sein,

richtiger ist es, an die funktion einen pointer auf eine variable im scope des aufrufenden programmteiles mitzugeben

signatur der funktion wäre dann: void plus(int x, int y, int* c);

lama007

OC Addicted
Avatar
Registered: Mar 2002
Location: Austria
Posts: 851
ziehmlich tückisch, in C zu programmieren - wenn man Glück hat, bricht das Programm ab.

habe bis jetzt damit jedesmal das richtige Ergebnis bekommen - aber mit einer Fehlermeldung beim Kompilieren : warning: function returns address of local variable

semteX

begehrt die rostschaufel
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14701
Zitat von lama007
ziehmlich tückisch, in C zu programmieren - wenn man Glück hat, bricht das Programm ab.

habe bis jetzt damit jedesmal das richtige Ergebnis bekommen - aber mit einer Fehlermeldung beim Kompilieren : warning: function returns address of local variable
ja, weil am stack noch ned drübergeschrieben wurde... mach zwischn "return" und auslesen der variable noch nen funktionsaufruf, wo du ein paar variablen deklarierst... dann wars das mim inhalt ;)

und ja, c / c++ is in der hinsicht sehr haarig... das (und die massive Gefahr von buffer overruns) is a riesen sicherheits problem... (+ zeiger arithmetik, mit der ma ja auch wie irre im speicher herumschreiben kann)

lama007

OC Addicted
Avatar
Registered: Mar 2002
Location: Austria
Posts: 851
Ok, ich hab's geschafft, das Ergebnis ist falsch.



Zitat von DirtyHarry
richtiger ist es, an die funktion einen pointer auf eine variable im scope des aufrufenden programmteiles mitzugeben

signatur der funktion wäre dann: void plus(int x, int y, int* c);

Kannst du mir kurz zeigen, wie mein Beispiel dann aussehen würde?

semteX

begehrt die rostschaufel
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14701
Code:
#include <stdio.h>
  
void plus(int x, int y, int* c);
 
int main( void ) { 	
  int a = 2, b = 3;
  int c = 0;
  plus(a, b, &c);
  printf("%d\n", c);
  getchar();
  return(0);
}
 
void plus( int x, int y, int* c) {  
  *c = x + y;
}
Bearbeitet von semteX am 08.02.2009, 21:28

prayerslayer

Oar. Mh.
Avatar
Registered: Sep 2004
Location: vorm Sucher
Posts: 4073
//recht gehabt, aber geowned worden.

lama007

OC Addicted
Avatar
Registered: Mar 2002
Location: Austria
Posts: 851
Code:
#include <stdio.h>
#define MAX 255

char *eingabe( void );

int main( void )
  {
  printf( "\n%s\n", eingabe() );
  return( 0 );
  }

char *eingabe( void )
  {
  char input[MAX];
  char * ptr = input;
  
  printf( "Eingabe: " );
  fgets( input, MAX, stdin );

  printf( "%p\n", input );
  printf( "%p\n", ptr );
  
  return( ptr ); /* return( input )*/
  } 

Warum funktioniert "return( ptr )" im Gegensatz zu "return( input)" ohne Fehlermeldung?

Beide sind local und beide geben die gleiche Adresse zurück.

-

Welche Funktion hat das "getchar" nach der printf-Anweisung im obigen Beispiel?

prayerslayer

Oar. Mh.
Avatar
Registered: Sep 2004
Location: vorm Sucher
Posts: 4073
1. frage: hab eine vermutung, kenn mich in C aber nicht allzu gut aus und möcht nix falsches sagen. was sagt die fehlermeldung des compilers?

2. frage: getchar() wartet auf eine eingabe, sodass du den output des programms noch lesen kannst, bevor es mit return beendet wird.

semteX

begehrt die rostschaufel
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14701
dein beispiel funktioniert bei mir genau gar ned... weder noch.

I'll fix that...

edit: das ist schon wieder der selbe mist wie zuvor. du definierst in der unterfunktion ein character array, haust nen zeiger drauf und returnierst => character array wird freigegeben und weg isses.

edit2: der compiler weist dich sogar drauf hin:

1>.\main.cpp(21) : warning C4172: returning address of local variable or temporary

edit3: and i fixed it.
Code:
#include <stdio.h>
#define MAX 255
 
char *eingabe(char* input);
 
int main( void ) {
  char input[MAX];
  //Die &input[0] gschichte ist ned notwendig, input würd eigentlich auch reichen.
  //aber so ists eventuell logischer für dich.
  printf( "\n%s\n", eingabe(&input[0]) );
  getchar();
  return( 0 );
}

char *eingabe(char* input) {   
  printf("Eingabe: ");
  fgets(input, MAX, stdin);  
  return(input); /* return( input )*/
}

edit4: getchar is nur da, damit ich mir im visual studio noch gschwind den output anschaun kann, macht sonst gar nix (und ja, es is ned schön, wayne)
Bearbeitet von semteX am 09.02.2009, 17:22

watchout

Legend
undead
Avatar
Registered: Nov 2000
Location: Off the grid.
Posts: 6845
Ich frag mich grad welchen compiler (und welche options) du (lama) verwendest :)

Warum das eine funktioniert und das andere nicht, könnte daran liegen dass dein Compiler eben nicht feinheiten durchcheckt wie welche werte eine variable haben kann. Ein char Array ist zwar vielleicht das gleiche wie ein Pointer auf das erste Element einer Folge von Chars im Speicher, das muss ein Compiler für Optimierungen und Sanity-Checks aber nicht unbedingt genauso sehen.

semteX

begehrt die rostschaufel
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14701
edit: das was unten steht stimmt nicht.

fgets hat bei max_characters schon das terminierungszeichen drinnen. ich lass es aber trotzdem mal stehen weil es etwas ist, wo man gern rein fällt (also array anfüllen ohne platz fürs terminierungszeichn zu lassen)

_____________________


und du hast noch nen weiteren fehler drin. du hast ein chararray mit MAX chars und liest MAX chars ein.

angenommen wir machn MAX = 5.

asdf = ok
asdfg = array voll, kein platz mehr für die terminierung, programm tot, sicherheitslücke offen.

fgets(input, MAX-1, stdin);

behebt dieses problem
Bearbeitet von semteX am 09.02.2009, 17:35

lama007

OC Addicted
Avatar
Registered: Mar 2002
Location: Austria
Posts: 851
Ich denke das mit "MAX-1" und warum dein Beispiel mit "return( input )" funktioniert habe ich verstanden.
Das mit "return( ptr )" ist mir noch nicht klar.

"gcc --version" gibt bei mir das aus:
"gcc (SUSE Linux) 4.3.2 [gcc-4_3-branch revision 141291]"
...

Mein Beispiel ist eine gekürzte Version von
Code:
#include <stdio.h>
#include <string.h> 
#define MAX 255  

char *eingabe(char *str) 
  {    
  char input[MAX];    
  char *ptr=input;    
  printf("Bitte \"%s\" eingeben: ",str);    
  fgets(input, MAX, stdin);     
  return ptr; 
  }  

int main() 
  {    
  char *ptr;    
  ptr = eingabe("Vorname");    
  printf("Hallo %s\n",ptr);     
  ptr = eingabe("Nachname");    
  printf("%s, interssanter Nachname\n",ptr);    
  return 0; 
  }  

aus "C von A bis Z" 15.6.1 (Zeiger als Rückgabewert), letzte Beispielversion.
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz