Lokale Variablen returnen
-
Hi,
ich bin mehr oder weniger unfreiwillig in C gelandet und hab eine Frage.
Ich hab eine Methode die mir ein Char Array zurückgeben soll (was zufällig von einer seriellen Schnittstelle liest, keiner Scherz)
Grob sieht das bei mir so auschar* gibWas(){ char wort[5]; // Packe da chars und den Nullterminator rein return wort; }
Funktioniert ja nicht, weil die lokale Variable im Scope außerhalb nicht exisiert, was mich ein wenig verwundert, da ich ja nur den Zeiger will und in dem char Array ist nur noch Müll drin.
Nur zur Info : Ich kann auf keine Libs zurückgreifen.Gibt es da eine schönere Methode das irgendwie hinzubekommen?
Ich könnte noch in gibWas mit malloc den Speicher reseriveren. Ist das der gangbare weg? Ich müsste dann später nur zusehen, dass ich die variablen, auf die die Referenz zurückgeht wieder lösche, nicht wahr?also sowas wie
char* gibWas(){ // Malloc char (Habs Syntax vergessen...) char wort[5]; // Packe da chars und den Nullterminator rein return wort; } char p = gibWas(); // Mach was mit p free(p);
?
-
char* gibWas() { char *wort = malloc(5); // ... // mach was mit '*wort' // ... return wort; }
-
Du hast drei Möglichkeiten, wie du dein Problem lösen kannst (daß es so direkt nicht geht, hast du ja schon selber erkannt):
- dynamisch angeforderter Speicher:
char* gibWas(...); { char* ret = malloc(5); ... return ret; } ... char* p = gibWas(...); ... free(p);
Hier muß sich halt der Aufrufer darum kümmern, den Speicher wieder freizugeben, sonst füllst du dir auf Dauer den RAM mit unerreichbaren Speicherblöcken.
- statische Variable:
char* gibWas(...); { static char ret[5]; ... return ret; } ... char* p = gibWas(...); ...
Hier braucht der Aufrufer sich nicht um den Speicher zu kümmern, allerdings wird der Array-Inhalt bei jedem Aufruf von gibWas() neu überschrieben - wenn du die früheren Werte weiterverwenden willst, mußt du sie rauskopieren.
- Übergabe des Ziels als Parameter:
char* gibWas(char* ret,...) { ... return ret; } ... char str[5]; gibWas(str,...);
Das Hauptprogramm muß sicherstellen, daß ausreichend Platz verfügbar ist (entweder du legst die benötigte Größe fest oder du läßt dir als weiteren Parameter mitteilen, wieviel Platz du zur Verfügung hast).
(unter C++ hast du noch eine vierte Möglichkeit - std::string)
-
Ehm, ok danke, das hätten wir gefixt, ich hatte es irgendwie komplexer in Erinnerung
Und schon hat noch jemand gepostet
Danke auch dir. Das problem mit der statischen Variable ist, dass die Methoden aus nem Stream liest, ist ein Wrapper fürs lesen und wenn man immer nur eine var hatm ist das doof wenn man erst kommando dann parameter liest und kommando vergißt, weil parameter auf die selbe stelle geschrieben worden ist
Da scheint das mit der Übergabe schon schön zu sein.
Was ich am letzten Beispiel nicht verstehe ist, warum ich noch die größe wissen muss, ich hab doch im Hauptprogramm bereits 5 Bytes reserviert, was muss die gibWas methode denn noch wissen?(Ich kommen eigentlich aus verwalteten Sprachen... :D)
-
Seikilos schrieb:
Was ich am letzten Beispiel nicht verstehe ist, warum ich noch die größe wissen muss, ich hab doch im Hauptprogramm bereits 5 Bytes reserviert, was muss die gibWas methode denn noch wissen?
Das Hauptprogramm weiß, daß es fünf Byte reserviert hat, die Funktion nicht. Deshalb kann sie entweder davon ausgehen, daß dort (mindestens) 5 Byte zur Verfügung stehen, oder sie lässt sich vom Hauptprogramm sagen, wieviel Platz verfügbar ist.
(selber berechnen kann sie's nicht, weil sie 'nur' einen Zeiger bekommt - und sizeof(ret) wird immer den selben Wert (idR 4) liefern, egal was das Hauptprogramm übergibt)
-
Achso!, naja problematischerweise muss bei mir alles wohl 255 sein, weil man ja von einer schnittstelle liest und nicht genau sagen kann, was was ist.
Aber danke, soweit ist es mir jetzt klar. Und vielleicht komm ich doch noch weg von 255, is ja nicht so, dass ich unendlich viel kb hätte