Pointer als Rückgabewert einer Funktion
-
Deine Funktion erstellt das Feld auf dem Stack und nicht auf dem Heap. Der Stack wird aber bei Funktionsende wieder abgeräumt, Dein Feld existiert dann nicht mehr. Der Pointer, den Du zurückgibst, zeigt deshalb auf ungültigen Speicherbereich.
Um Speicher auf dem Heap zu reservieren, benutze die Funktion malloc.
-
Okay, ich überarbeite noch ein mal alles und poste die Antwort dann später noch mal, in der Hoffnung, das mehr richtig ist.
Danke.
-
Also, ich habe meinen Code verbessert.
Die einzige Frage, die mir bleibt ist, ob ich die Feldwerten in der Funktion auf Null setzen muss, oder ob es reicht, wenn ich sie einfach nicht deklariere.
Naja, hier mein Code:#include<stdio.h> #include<stdlib.h> //#define getCoordinateArray(x) calloc((x),sizeof(coordinate_t)) typedef struct { float x; float y; } coordinate_t; coordinate_t * getCoordinateArray (int n) {coordinate_t* point; point = (int*)malloc(sizeof(coordinate_t)); coordinate_t Feld[n]; return point; } int main ( void) { coordinate_t * q; int i = 0; q = getCoordinateArray(10); for ( i=0; i < 10; i++) printf("(%f,\n%f)\n", q[i].x, q[i].y); free(q); return 0; }
-
Die Funktion sollte so aussehen
coordinate_t * getCoordinateArray (int n) { return (coordinate_t*)calloc(sizeof(coordinate_t) * n); // Wichtig: * n und (coordinate_t*) }
calloc füllt das feld mit 0 (ist aber langsamer)
-
Für wieviele Elemente vom Typ coordinate_t legst Du in Z.14 Speicherplatz an?
Welche Überlegung steht hinter dem cast in Z.14?(int*)
Welche Überlegung steht hinter dem VLAFeld
in Z. 15?Schalt die Warnungen in Deiner IDE ein! Der Compiler sieht viel mehr Merkwürdigkeiten als Du!
-
Und so wie ich es gemacht habe, ist es nicht richtig?
wenn ich mein Programm ausführe, bekomme ich auch 0.0000 als Feldwert zurück.
-
Stimmt, das (int*) ist natürlich vollkommen unsinnig!
Klar, das Feld brauche ich gar nicht, da in main() eines angelegt ist.Was ich nicht verstehe ist das:
calloc(sizeof(coordinate_t) * n); // Wichtig: * n und (coordinate_t*)
Wieso das *n?
Und kann man den cast vor malloc nicht weg lassen? (Oder ist das bei calloc anders geregelt?)Danke.
-
Du hast auf dem Heap aber nur Speicher für eine einzige struct reserviert. Außerdem ist die Definition von Feld sinnlos.
Der cast des Rückgabewertes von malloc ist 1. überflüssig und 2. in Deinem Fall auch noch falsch.
-
Naja, sizeof(coordinate_t) ist die Größe eines structs. Du willst aber Platz für n structs, deshalb:
sizeof(coordinate_t) * n
// in Worten: mal n
-
Haloelite2 schrieb:
Klar, das Feld brauche ich gar nicht, da in main() eines angelegt ist.
Nein. Das Feld brauchst Du gar nicht, weil Du es einfach nicht brauchst ...
Wo ist denn in main eines angelegt?Edit:
Ach ja, natürlich solltest Du - wie in der Aufgabe verlangt - die Feldelemente in Deiner Funktion auch (mit 0) initialisieren!
-
In Ordnung, dann mal vielen Dank, an alle die geholfen haben.
ich denke, ich habe es wenigstens vom Prinzip her verstanden.
-
for ( i=0; i < 10; i++) printf("(%f,%f)\n", q[i].x, q[i].y);
Stimmt, mit q[i].x, bzw. q[i].y sind ja Speicherstellen (soweit ich weiß) gemeint.
Schon peinlich.
-
coder777 schrieb:
return (coordinate_t*)calloc(sizeof(coordinate_t) * n); // Wichtig: * n und (coordinate_t*)
Das ist falsch!#
calloc erwartet zwei Paramter
malloc erwartet einen Paramterhttp://www.cplusplus.com/reference/cstdlib/calloc/
http://www.cplusplus.com/reference/cstdlib/malloc/
-
Schreib Dir eine Funktion für das "initialisieren" solcher Felder und eine für die Ausgabe.
// Weist den ersten n coordinate_t Objekten im Array base die Werte x und y zu void coordinate_init(coordinate_t *base, int n, float x, float y); // Gibt die ersten n coordinate_t Objekte im Array base nach stdout aus. void coordinate_print(const coordinate *base, int n);
Vergiss nicht den Rückgabewert von
getCoordinateArray()
inmain()
zu testen. Eventuell konnte nicht genügend Speicher alloziert werden undmalloc()
gibtNULL
zurück.
Überleg Dir auch, zu überprüfen ob der Parameter n in irgendeiner der Funktionen negativ ist - das wäre wohl ein Fehler vom Aufrufer.
-
Also in meinem Fall malloc benutzen?
-
Haloelite2 schrieb:
Also in meinem Fall malloc benutzen?
Ich habe nur an den Lerneffekt gedacht.
Die
calloc()
Lösung funktioniert übrigens nur, wenn die 0 alsfloat
wirklich kein Bit gesetzt hat. Das ist wohl bei so ziemlich jedem System der Fall - aber 100% ist es nicht.
Du kannst das natürlich testen...blabla... Aber warum?! Nimmmalloc()
und initialisier selber.#if __STDC_IEC_559__==1 #define getCoordinateArray(x) calloc((x),sizeof(coordinate_t)) #else coordinate_t *getCoordinateArray(int n) { coordinate_t *result = malloc(n*sizeof(coordinate_t)); if(result) coordinate_init(result, n, 0.f, 0.f); return result; } #endif
-
Okay, diese Zeile verstehe ich nicht:
f(result) coordinate_init(result, n, 0.f, 0.f);
-
Haloelite2 schrieb:
Okay, diese Zeile verstehe ich nicht:
if(result) coordinate_init(result, n, 0.f, 0.f);
Na: das ist halt ein Aufruf von der Funktion, die ich Dir vorschlug, dass Du Sie noch implementierst.
Und ich prüfe
result
vor dem Aufruf aufNULL
- fallsmalloc()
wirklich keinen Speicher klarmachen konnte.
-
Ich soll lediglich (Aufgabenstellung) die gegebene Funktion vervollständigen.
Außerdem verstehe ich auch noch nicht, wie ich die Werte des array (Es ist doch keines deklariert) auf 0 setzen soll.
Außerdem bekomme ich als Ausgabe ohnehin nur Nullen angezeigt, von daher sollte es schon mit 0 belegt sein, oder?
-
coordinate_t * getCoordinateArray (int n) { coordinate_t* p = malloc( n * sizeof(*p) ); if( p!=NULL ) while( n-- ) p[n].x = p[n].y = 0; return p; }
Und was war jetzt so schlimm daran?
Du hast im Unterricht nicht aufgepasst (als malloc dran war) und auch sonst nicht.