Durch Pointer verwirrt... (Wie gehts richtig?)
-
Hallo zusammen ...
Durch Pointer kann man ja die Speicheradressen an Funktionen übergeben und so dafür sorgen, dass der Inhalt einer Variable, wenn er in der Funktion geändert ist auch im Hauptprogramm geändert ist.
So zum Beispiel:
#include <iostream> void Test(char *text) { int i; for (i=0;i<5;i++) text[i]='u'; } int main() { char text[128]="Test"; printf("%s\n",text); Test(text); printf("%s",text); return 0; }Ich habe also in Main ein Array, dessen Adresse übergebe ich in Test. Dort wird der Inhalt der Speicheradressen verändert, sodass ich die aktuellen Werte in Main wieder abrufen kann.
Soweit so klar!Jetzt wollte ich das Ganze aber gern umgedreht

Also in Test ein Array auf welches ich in Main gern zurück greifen würde. Wird irgendetwas am Array in Test geändert, soll man es auch gleich in Main merken.
Meine Idee, war also eventuell die Adresse des 0ten Arrayfeldes von der Test-Funktion zurück geben zu lassen und dann in Main den Pointer diese Adresse zuweisen zu lassen.
Also so:#include <iostream> char Test() { int i; char Zeile[20]="Da........"; return &Zeile[0]; } int main() { char text[128]="Test"; printf("%s\n",text); &text[0]=Test(); printf("%s\n",text); return 0; }Das klappt aber nicht. Ich erhalte den Fehler: "error C2440: '=': 'char' kann nicht in 'char *' konvertiert werden".
Wo liegt mein Denkfehler?

Und vor allem: Wie bekomm ichs hin?Danke für euere Hilfe!

-
Das ist kein C++, willst du es mit C++ oder C machen? Wenn C, dann falsches Forum, aber dann wirst du sicherlich verschoben.
-
Ganz wichtig: Man gibt keinen Pointer auf eine lokale Variable zurück, da ja die lokale Variable nach verlassen des Prozedur gelöscht wird --> undefiniertes Verhalten.
Dein Rückgabewert der Funktion ist ein Pointer, schau mal deinen Methodenkopf an was du als Rückgabewert angegeben hast...
#include <stdio.h> char* test() { static char* x = "Das ist ein Test"; // static: x ist auch nach verlassen der Prozedur noch vorhanden --> kein undefiniertes Verhalten return x; } int main() { char* text = "Huhu"; while(*text) { printf("%c", *text++); } printf("\n"); text = test(); while(*text) { printf("%c", *text++); } printf("\n"); free(test); test = NULL; return 0; }
-
Ein bischen Korrektur...
Ravendark schrieb:
[...]
#include <stdio.h> char* test() { static char* x = "Das ist ein Test"; // static: x ist auch nach verlassen der Prozedur noch vorhanden --> kein undefiniertes Verhalten return x; } int main() { char* text = "Huhu"; /* while(*text) { printf("%c", *text++); } printf("\n"); */ printf("%s\n", text); text = test(); /* while(*text) { printf("%c", *text++); } printf("\n"); */ printf("%s\n", text); /* Autsch! free(test); test = NULL; */ return 0; }Oder mit C++
#include <iostream> #include <string> std::string Test() { return "Hallo Du da!"; } int main() { std::string text = "Alter Text."; std::cout << text << '\n'; text = Test(); std::cout << text << '\n'; return 0; }
-
@Tachyon
und nun schreiben wir hundert mal an die Tafel: Globale variablen sind Boese (besonders wenn man sie ned wirklich notwendig sind).
Das gilt auch fuer die gut versteckten !
@Mandel
den richtigen C++ weg hat dir Tachyon in seinem 2.Beispiel schon gezeigt, mit contaeinern, tiefen kopien und tiefen vertrauen in die optimierungsfaehigkeiten unseres compilers.Bei C gibts keinen so nen Weg. In c wird normal nie in zeiger auf einen "selbsterzeugten" Speicherbereich zurueckgegeben.
Aufn stack gibts nen Error, weil der Stack beim verlassen eh zurueckrollt und der zeiger ins Nirvana zeigen wuerd, und dynamischer Speicher, da wuerdest gegen eine Programmier Regel verstossen, die Lautet: Erzeuge dynamsichen Speicher im selben context (also COde Block oder Konstruktor/destructor ).
Du wuerdest nen sehr fehelerannfaelliges Interface bekommen (weil dein user den speicher irgendwo expliziet wieder freigeben muss, wahrscheinlich mit ner von dir definierten funktion) und ausserdem wuerdest die art das speichers von vornherein festlegen.
Ausserdem braucht man unter C meist soweiso nen Fehlercode, da C keine exceptions kennt.besser man laesst die funktion in dem vom aufrufer spezifizierten speicher schreiben, dann hat er zwar mehr arbeit, aber auch die groessere flexibilitaet.
Weisst du vornherein nicht, wie gross dein benoetigter speicher ist, dann gib der funktion nen Mode, wo sie den expliziet uebermitteln kann.int Test(char *buffer,size_t * buffersize) { int ireturn = ERROR_INVALIDBUFFERSIZEVARIABLE; if(buffersize) { if(buffer) { for(i=0;i<min(5,*buffersize);i++) { buffer[i]='u'; } ireturn = *buffersize < 5 : ERROR_BUFFERTOSMALL : SUCCESS; } else { /// buffer = NULL, der usser will die grosse wissen *buffersize = 5; ireturn = SUCCESS; } } }Verwenden koennte man das dann so:
/// statisch: char buffer[128]; memset(buffer,0,128); size_t size = 128; if(Test(buffer,&size) == SUCCESS) { std::cout << buffer; } else { // fehlerbehandlung, wenn der buffer ned grossgenug war } /// und dynamisch: char * dynBuffer = NULL; size_t size = 0; if(test(dynBuffer ,&size) == SUCCESS) { if(size > 0) { /// dynamisch den buffer erzeugen dynbuffer = (char *)malloc(size +1); // um 1 groesser fuer zeichenendezeichen memset(dynbuffer,0,size + 1); if(test(dynBuffer ,&size) == SUCCESS) { /// Ausgabe std::cout << dynBuffer; } else { /// Fehlerbehandlung } } }Das waer sauberes C
Ciao ...