Zeiger als Rückgabewert
-
Hi Leute,
ich habe ein kleines Problem mit einem Zeiger. Folgendes vereinfachtes Beispiel:
#include <stdio.h> #include <stdlib.h> #include <iostream> typedef struct myStruct { int wert; int *optional; } myStruct_t; myStruct *myFunc(bool crash) { if (crash) {return NULL;} myStruct *Temp; Temp = (myStruct*) calloc(1, sizeof(*Temp)); return Temp; } int main () { myStruct newStruct; /* kein pointer */ newStruct = *myFunc(false); newStruct = *myFunc(true); // crash return 0; }
Ich habe eine Funktion, die bei Erfolg einen Zeiger zurückgibt. Tritt ein Fehler auf, so gibt diese stattdessen NULL zurück. Im Beispiel wird das mal über den Parameter "crash" simuliert. In der main-Funktion möchte ich diesen Rückgabewert als eine Struktur vom Typ myStruct_t speichern, die allerdings nicht vom Typ her ein Zeiger ist. Beim Aufruf der Zeile "newStruct = *myFunc(true);" stürzt das Programm ab.
...ok, soweit ich weiß ist sowas nicht erlaubt:
int *pWert; int Wert; Wert = pWert;
Wie gehe ich hier am besten vor? Ich könnte natürlich die Funktion wie folgt ändern:
int myFunc(myStruct &Temp);
...aber das wollte ich in diesem Fall vermeiden, da diese Funktion ein Teil einer externen Lib ist. Muss ich eventuell mit memcopy arbeiten und anschließend free() auf den zeiger anwenden?
Wie kann ich das am elegantesten lösen?viele Grüße,
SBond
-
Du solltest NICHT auf den Inhalt der Zeigervariablen zugreifen, wenn der Zeiger NULL ist !!!
Gruss
Frank
-
ja da hast du recht
Kann man den Rückgabewert prüfen, bevor man ihn zuweist? Ober muss ich vorher eine Hilfsvariable erzeugen?:
myStruct *temp = myFunc(true); if (temp != NULL) { newStruct = *temp; }
...das würde funktionieren, aber es wirkt irgendwie umständlich. Muss ja zu meiner Schande gestehen, dass ich kein großer Feund von Zeigern bin.
noch so nebenbei: ist die Zuweisung in diesem Fall eine Kopie oder müsste ich mit Datenverlust rechnen, wenn ich nach der Zuweisung free() auf den Zeiger anwende? Möchte natürlich auch Speicherlecks vermeiden, aber ich bin da etwas unsicher.
-
Du wirst nicht umhin kommen, mit der Hilfsvariable zu arbeiten.
free() kannst du auch für NULL-Zeiger gefahrlos aufrufen.
Ob du überhaupt free() aufrufen musst, kann nur die Dokumentation zu deiner verwendeten Library sagen;
oftmals werden zwar Zeiger rückgegeben, die aber nur auf lokal-statischen Speicher zeigen, und den darfst du dann eben nicht mit free() aufrufen, sondern nur, wenn es dynamischer Speicher von malloc,calloc,realloc ist.
-
ok, danke für die tipps
-
Deine Funktion heißt myFunc und nicht *myFunc.
-
wie jetzt
myStruct *myFunc(bool crash)
das die Funktion einen zeiger zurückgibt ist quasi von der Lib gegeben
-
DirkB bezieht sich auf Deine Zeilen 28 und 29. Dir ist klar, dass das Sternchen dort nicht Teil des Funktionsnamens ist? Sondern dass du dadurch, dass du dort ein Sternchen schreibst, den zurück gegebenen Zeiger dereferenzierst?
Also dass
newStruct = *myFunc(false);
das gleiche ist wie
newStruct = * (myFunc(false));
oder mit Hilfsvariable:
myStruct newStruct; myStruct *hilfszeiger; hilfszeiger = myFunc(false); newStruct = *hilfszeiger;
Damit sollte dann wohl auch klar sein, wieso das abstürzt, wenn der Rückgabewert NULL ist.
Du benutzt übrigens einen C++-Compiler für deinen C-Quelltext. Tu das nicht! Die beiden Sprachen sind trotz historischer Ähnlichkeiten zu verschieden, als dass man diese Unterschiede ignorieren könnte, wenn es über einfachste Beispielprogramme hinaus geht.
-
die Dereferenzierung war mir hier bewusst. In meinem eigentlichen Quellcode war mir das nicht bewusst (zumindest die Tatsache dass die Rückgabe auch NULL sein konnte). Erst ein Absturz hat mich beim Testen darauf aufmerksam gemacht. Ich mag keine Zeiger
Woher hast du den C/C++ unterschied erkannt? Weil ich 'calloc' statt 'new' verwendet habe? Ich muss scheinbar noch viel lernen
-
SBond schrieb:
Woher hast du den C/C++ unterschied erkannt? Weil ich 'calloc' statt 'new' verwendet habe? Ich muss scheinbar noch viel lernen
#include <iostream> <-- das ist kein C, der Rest vom Programm aber schon.
-
ja ich bin leider noch ein C++ Anfänger
Mit AutoIt und PureBasic war die Welt noch so einfach
...nur leider kein OOP. naja ^^
-
Zeiger sind in erster Linie C
-> Literaturtip:
-
Dieser Thread wurde von Moderator/in nachtfeuer aus dem Forum Rund um die Programmierung in das Forum C (alle ISO-Standards) verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
420815 schrieb:
SBond schrieb:
Woher hast du den C/C++ unterschied erkannt? Weil ich 'calloc' statt 'new' verwendet habe? Ich muss scheinbar noch viel lernen
#include <iostream> <-- das ist kein C, der Rest vom Programm aber schon.
Das war nur der Beweis. Da sind noch mehr C++-Features, die aber in späteren C-Standard übernommen wurden (beispielsweise der Name des structs). Ich habe bloß nicht den Eindruck, dass der Threadersteller irgendwelche höheren C-Standards in seinem Compiler aktiviert hat.