Array als Rückgabewert
-
Wenn ich wie oben beschrieben den Funktionskopf so mache:
float* vectorXproduct(a[3],b[3]);
dann habe ich noch das Problem das ergebnis wieder in ein Array zu casten. Wie mache ich das? Weil
zAxis[3] = (float[3])vectorXproduct(a,b);Ist laut ISO C++ verboten. (sagt mein Compiler)
-
Grüß Dich,
Anfänger06 schrieb:
float* vectorXproduct(float a[3], float b[3]) { float result[3] = {0,0,0}; /* Die eigentliche Rechnung */ return (float*)result; }Folgendes passiert hier:
Du rufst die Funktion mit den Parametern a und b auf. Auf dem Stack werden zusätzlich 12 Bytes belegt um die Werte für result zu speichern.
Die Werte für Result werden berechnet, in result gespeichert, die Funktion verlassen - damit werden die 12 Byte an den Stack wieder zurückgegeben.
Ob überhaupt und wenn ja wie lange, die Werte noch auf der zurückgegebenen Position "result" liegen, ist undefiniert.
Sobald der Compiler etwas RAM braucht, wird er sich wieder vom Stack bedienen und Dein "result" überschreiben.
Darum ist die Funktion falsch!Du kannst eine Funktion schreiben, der Du angibst, wo sie das Ergebnis reinschreiben darf:
float* vectorXproduct(float a[3], float b[3], float * result)Aufruf
float result[3]; zAxe = {0,0,1}; vectorXproduct(zAxe, vec, result);oder Du belegst Speicher:
float* vectorXproduct(float a[3], float b[3]) { float * result = new float[3]; result[0] = result[1] = result[2] = 0; /* Die eigentliche Rechnung */ return result; }Den Speicher musst Du am Ende natürlich wieder freigeben.
float * result; zAxe = {0,0,1}; result = vectorXproduct(zAxe, vec); /* result verwenden */ delete result;Du solltest, meiner Meinung nach, die erste Möglichkeit bevorzugt verwenden.
-
Ok...Das rückcasten kann ich umgehen. Wäre aber trotzdem schön zu wissen wie man einen Pointer rückgabewert, in ein als Array vereinbarten Wert speichert.
-
Anfänger06 schrieb:
Ok...Das rückcasten kann ich umgehen. Wäre aber trotzdem schön zu wissen wie man einen Pointer rückgabewert, in ein als Array vereinbarten Wert speichert.
Du kannst den Pointer ja wieder zurückgeben. Aber Du solltest die Ergebnisse irgendwo hinschreiben, wo sie verfügbar bleiben und im Idealfall sagst Du der Funktion, wo sie ihr Ergebnis hinschreiben soll, damit sie nicht selber Speicher besorgen muss und die Speicherverwaltung überschaubarer bleibt.
Rückgabe wäre dann der selbe Pointer wie das 3. Argument, nur dass sich die Werte an der Adresse inzwischen geändert haben.
-
Elementweise

float* res = func(); float value[3]; for(i=0;i<3;++i) value[i]=res[i];aber noch besser ist es trotzdem, die Möglichkeiten von C++ zu nutzen - und das einfachste ist es, dein Array in eine Klasse einzupacken:
class mathVector { public: mathVector() {} mathVector(float* val) {for(int i=0;i<3;++i) data[i]=val[i];} mathVector(float x,float y,float z) {data[0]=x;data[1]=y;data[2]=z;} ... private: float data[3]; }
-
[quote="CStoll"]Elementweise

for(i=0;i<3;++i) value[i]=res[i];Es gibt auch Punkte, da ist eine Schleife übertrieben.
Bei einem Vektor mit 3 Dimensionen ist dieser Punkt imho erreicht. ^^CStoll schrieb:
aber noch besser ist es trotzdem, die Möglichkeiten von C++ zu nutzen - und das einfachste ist es, dein Array in eine Klasse einzupacken:
Grundsätzlich stimme ich zu.
Ich glaube aber, wenn jemand soeben gelernt hat, dass lokale Variablen bei Verlassen der Funktion die Gültigkeit verlieren, dann sind die Möglichkeiten von C++ Dinge, die er auch morgen noch lernen kann. :->
-
Xin schrieb:
Es gibt auch Punkte, da ist eine Schleife übertrieben.
Bei einem Vektor mit 3 Dimensionen ist dieser Punkt imho erreicht. ^^Ansichtssache
Und so viel langsmaer dürfte eine Schleife gegenüber "value[0]=res[0];value[1]=res[1];value[2]=res[2];" nicht sein (auf jeden Fall macht sie weniger Schreibarbeit und ist übersichtlicher).CStoll schrieb:
aber noch besser ist es trotzdem, die Möglichkeiten von C++ zu nutzen - und das einfachste ist es, dein Array in eine Klasse einzupacken:
Grundsätzlich stimme ich zu.
Ich glaube aber, wenn jemand soeben gelernt hat, dass lokale Variablen bei Verlassen der Funktion die Gültigkeit verlieren, dann sind die Möglichkeiten von C++ Dinge, die er auch morgen noch lernen kann. :->OK, dann warten wir noch etwas damit - trotzdem setzen wir als nächste Lektion an: Arrays lassen sich NICHT per =Operator kopieren, Objekte schon.
-
Anfänger06 schrieb:
Deshalb wüsste ich gern wie ich diese Funktion umschreiben muss, damit die Funktioniert:
float* vectorXproduct(float a[3], float b[3]) { float result[3] = {0,0,0}; /* Die eigentliche Rechnung */ return (float*)result; }Das ganze soll dann mal so aufgerufen werden:
float zAxe = {0,0,1}; zAxe = vectorXproduct(zAxe, vec);probier dies:
typedef struct myvector { float f[3]; } MYVECTOR; MYVECTOR vectorXproduct (MYVECTOR a, MYVECTOR b) { MYVECTOR result = {0.0, 0.0, 0.0}; /* Die eigentliche Rechnung */ return result; }geht in c etwa so, in c++ bestimmt ähnlich/auch
-
[quote="net"][quote="Anfänger06"]
typedef struct myvector { float f[3]; } MYVECTOR;Jow...
der Nick hieß "Anfänger06"... und das Problem war, dass er nicht wußte, dass lokale Variablen im Nirvana verschwinden.<zyn>Vielleicht sollte noch jemand Templates vorstellen... die Lösung wäre für einen Anfänger noch komplizierter und damit komplett undurchführbar, aber noch viel besser.</zyn>
-
Xin schrieb:
<zyn>Vielleicht sollte noch jemand Templates vorstellen... die Lösung wäre für einen Anfänger noch komplizierter und damit komplett undurchführbar, aber noch viel besser.</zyn>
Also ich finde std::vector ist nicht sehr schwer auch nicht für einen Anfänger. Ist, finde ich eigentlich, die beste lösung.