Pointer auf mehrdimensionales Array zurückgeben
-
Hallo
Ich habe mir eine Funkton geschrieben, welche ein zweidimensionales Array allokiert, dieses füllt und danach einen Pointer auf das Array zurückgeben soll:
double* calcLorenz( double start, double end, double step, double x, double y, double z) { // allocate array for coordinates double (*arr)[3] = new double[int((end-start)/step)][3]; // set start coordinates arr[0][0] = x; arr[0][0] = y; arr[0][0] = z; // calculate coordinates while (start < end) { dglstep(3, start, arr[int(start/step)], step, (void (*)(double, double*, double*))compute ); start += step; } return *arr; }
Da ich einen Pointer zurückgeben will, ist die Funktion mit double* definiert. Danach wird das Array allokiert und über den Pointer arr angesprochen und zurückgegeben.
Danach sollte ich die Funktion ja irgendwie so aufrufen:
int main () { double *arr; arr = calcLorenz(0, 10, 0.01, 1, 1, 50); return 1; }
Was aber nicht funktioniert. OK, der Pointer ist vom Typ double* und nicht double (*arr)[3], wenn ich das aber so mache, kann ich dem Pointer aber die Adresse nicht mehr zuweisen.
Die Frage ist nun, wie ich diese Zuweisung machen muss, so dass ich dann ganz normal mit arr[x][0] auf die Werte zugreiffen kann?!?
Oder ist ev. sogar die Funktionsdefinition falsch?Besten Dank und Gruss
GierAffe
-
Mach's mal so
#include <iostream> using namespace std; double** Calc() { double** arr = new double*[10]; for(int i=0;i<10;i++) { arr[i]=new double[10]; } //... return arr; } int main() { double** arr= Calc(); cout << arr[0][0] << endl; cout << arr[1][0] << endl; cout << arr[0][5] << endl; cout << arr[9][5] << endl; for(int i=0;i<3;i++) { delete[] arr[i]; } delete[] arr; return 1; }
Anyway, ich würd's mit vectoren machen. Das ist viel schöner und du musst dich nicht um die Freigabe des Speichers kümmern...
-
Gieraffe schrieb:
Die Frage ist nun, wie ich diese Zuweisung machen muss, so dass ich dann ganz normal mit arr[x][0] auf die Werte zugreiffen kann?!?
Oder ist ev. sogar die Funktionsdefinition falsch?für diesen zweck, ja. die deklaration einer funktion, die einen pointer auf ein array zurückgibt, ist nicht trivial:
double (*calcLorenz( double start, double end, double step, double x, double y, double z))[3]
glücklicherweise gibt es ja auch noch typedefs. allerdings kann es sinnvoll sein, statt einem array eine klasse im stile von std::tr1::array einzusetzen.
-
Trundle0x7e schrieb:
double** arr= Calc(); cout << arr[0][0] << endl;
Wie soll das denn funktionieren? Es ist doch überhaupt nicht
klar was für eine 2. Dimension arr besitzt.
-
Javaner schrieb:
Trundle0x7e schrieb:
double** arr= Calc(); cout << arr[0][0] << endl;
Wie soll das denn funktionieren? Es ist doch überhaupt nicht
klar was für eine 2. Dimension arr besitzt.Aber arr[0] ist ein Zeiger (sogar initialisiert).
-
Javaner schrieb:
Trundle0x7e schrieb:
double** arr= Calc();
cout << arr[0][0] << endl;
[/cpp]Wie soll das denn funktionieren? Es ist doch überhaupt nicht
klar was für eine 2. Dimension arr besitzt.Ich habe es zwar nicht getstet, aber es sollte gehen?!
Der Rückgabewert ist einfach nur ein Zeiger auf einen Array von Zeigern(!), welche wiederum auf die echten Arrays zeigen.
Statt arr[0][0] könnte ich z.B: auch schreiben:
double* pFirstArray=*arr; double dFirstEntry=pFirstArray[0];
Oder statt arr[5][6] könnte ich z.B: auch schreiben:
double* pFifthArray=*(arr+5); double dFifthEntry=pFifthArray[6];
Ich seh jetzt da keine Probleme, welche der Compiler haben könnte?!
-
Trundle0x7e schrieb:
Der Rückgabewert ist einfach nur ein Zeiger auf einen Array von Zeigern(!), welche wiederum auf die echten Arrays zeigen.
Nein! Der Rückgabewert ist ein Zeiger auf einen Zeiger auf einen double.
Trundle0x7e schrieb:
Statt arr[0][0] könnte ich z.B: auch schreiben:
double* pFirstArray=*arr; double dFirstEntry=pFirstArray[0];
Das ist korrekt!
Trundle0x7e schrieb:
Oder statt arr[5][6] könnte ich z.B: auch schreiben:
double* pFifthArray=*(arr+5); double dFifthEntry=pFifthArray[6];
Das ist Falsch!
*(arr+5) ist gleich dem Inhalt der Adresse (arr+5*4) (falls sizeof(int**)==4 ist)
-
Javaner schrieb:
*(arr+5) ist gleich dem Inhalt der Adresse (arr+5*4) (falls sizeof(int**)==4 ist)
?
Ja. Ist doch richtig? Der Inhalt des fünften Elementes von arr, also &arr[5][0] oder arr[5]?!Ich schätze mal, ich habe dich falsch verstanden (oder du mich :P), aber das geht 100%tig:
#include <iostream> using namespace std; int main() { int** p=new int*[10]; for(int i=0;i<10;i++) { p[i]=new int[10]; for(int j=0;j<10;j++) { p[i][j]=i*10+j; } } cout << "Der 1337 test: Ausgabe von int** p" << endl; for(int i=0;i<10;i++) { for(int j=0;j<10;j++) { if(p[i][j]<10) { cout << " "; } cout << p[i][j] << " "; } cout << endl; } cout << "Der 1337 test ist jetzt vorbei :(" << endl; return 0; }
-
Ich versuchs anders herum:
double** arr= Calc(); cout << arr[1][3] << endl; cout << arr[1][3742] << endl; cout << arr[2][0] << endl;
Woher bitte soll der Compiler wissen, wie groß die
2. Dimension ist, also wo arr[2] beginnt?C++ ist nicht Java wo Arrays ihre Länge mitgespeichert haben.
Eine Längenangabe gibt es in C++ für Arrays nicht.Man kann sogar noch weiter gehen, daß es in C++ überhaupt keine Arrays
gibt; nur Zeiger auf irgendetwas. Das Konzept namens Array kennt nur der
Compiler.
-
Javaner schrieb:
Woher bitte soll der Compiler wissen, wie groß die
2. Dimension ist, also wo arr[2] beginnt?Muss er nicht wissen. arr[2] ist (arr+2), und das ist ein double, den er nur dereferenzieren muss. Er muss keine Adresse berechnen. Dass verschachtelte Arrays (es gibt eigentlich keine 2D-Arrays) und Zeigerarrays beim Dereferenzieren gleich aussehen kann manchmal verwirrend sein ...
C++ ist nicht Java wo Arrays ihre Länge mitgespeichert haben.
Eine Längenangabe gibt es in C++ für Arrays nicht.Komisches Argument. In Java gibts überhaupt keine verschachtelten Arrays wie in C++, sondern nur Arrays die wieder Pointer auf Arrays enthalten. Die Länge ist dabei vollkommen egal.
Man kann sogar noch weiter gehen, daß es in C++ überhaupt keine Arrays
gibt; nur Zeiger auf irgendetwas. Das Konstrukt namens Array kennt nur der
Compiler.Wenn der Compiler es kennt ist das gut genug, wer soll es denn noch kennen?
-
Javaner schrieb:
Man kann sogar noch weiter gehen, daß es in C++ überhaupt keine Arrays
gibt; nur Zeiger auf irgendetwas. Das Konstrukt namens Array kennt nur der
Compiler.Habe ich denn das Gegenteil behauptet?!
Ich definiere Array als eine Speicheradresse, die auf eine bestimmte Anzahl von Elementen vom Typ X zeigt, welche hintereinander gespeichert sind. Die Anzahl dieser Elemente ist zur Laufzeit nicht herausfindbar...Wo liegt jetzt aber das Problem konkret in meinem Code?!
-
Trundle0x7e schrieb:
aber das geht 100%tig:
int main() { int** p=new int*[10]; ...
Ja! Weil hier der Compiler weiß, daß jedes Element auf das
p zeigen kann eben 10 int-Elemente enthält.(Glaube ich jetzt zumindest
)
-
Javaner schrieb:
Trundle0x7e schrieb:
aber das geht 100%tig:
int main() { int** p=new int*[10]; ...
Ja! Weil hier der Compiler weiß, daß jedes Element auf das
p zeigen kann eben 10 int-Elemente enthält.(Glaube ich jetzt zumindest
)
Nö. Das ist ein 10-elementiges Array von int-Pointern. Was du meinst sähe so aus:
int (*p)[10] = new /* new-syntax ist schwer und ich hab keinen Bock nachzugucken, die Deklaration links ist das entscheidende */
-
Habe ich was verpasst?! Auch wenn er es nicht wissen sollte, wo liegt das Problem?!
#include <iostream> using namespace std; int main() { int iNumElements; cout << "Wie viele Reihen/Zeilen wünschst du, sehr junger Padawan?" << endl; cin >> iNumElements; int** p=new int*[iNumElements]; for(int i=0;i<iNumElements;i++) { p[i]=new int[iNumElements]; for(int j=0;j<iNumElements;j++) { p[i][j]=i*iNumElements+j+1; } } cout << "Der 1337 test part 2: Ausgabe von int** p" << endl; for(int i=0;i<iNumElements;i++) { for(int j=0;j<iNumElements;j++) { cout << p[i][j] << " "; } cout << endl; } cout << "Der 1337 testpart 2 ist jetzt vorbei :(" << endl; return 0; }
By the way: Warum hindert mich dieser Spamschutz vorm posten?!
-
Bashar schrieb:
Javaner schrieb:
Woher bitte soll der Compiler wissen, wie groß die
2. Dimension ist, also wo arr[2] beginnt?Muss er nicht wissen. arr[2] ist (arr+2), und das ist ein double, den er nur dereferenzieren muss. Er muss keine Adresse berechnen. Dass verschachtelte Arrays (es gibt eigentlich keine 2D-Arrays) und Zeigerarrays beim Dereferenzieren gleich aussehen kann manchmal verwirrend sein ...
Ich bezog mich auf diesen Code-Ausschnitt:
int main() { double** arr= Calc(); cout << arr[0][0] << endl; cout << arr[1][0] << endl; cout << arr[0][5] << endl; cout << arr[9][5] << endl; }
Woher soll hier denn der Compiler wissen, wo arr[1] beginnt?
Bashar schrieb:
C++ ist nicht Java wo Arrays ihre Länge mitgespeichert haben.
Eine Längenangabe gibt es in C++ für Arrays nicht.Komisches Argument. In Java gibts überhaupt keine verschachtelten Arrays wie in C++, sondern nur Arrays die wieder Pointer auf Arrays enthalten. Die Länge ist dabei vollkommen egal.
Eben! Das meinte ich doch.
Bashar schrieb:
Man kann sogar noch weiter gehen, daß es in C++ überhaupt keine Arrays
gibt; nur Zeiger auf irgendetwas. Das Konstrukt namens Array kennt nur der
Compiler.Wenn der Compiler es kennt ist das gut genug, wer soll es denn noch kennen?
Stimmt! Ich vergaß, daß C++ ja keine Interpreter-Sprache ist.
-
Javaner schrieb:
Ich bezog mich auf diesen Code-Ausschnitt:
int main() { double** arr= Calc(); cout << arr[0][0] << endl; cout << arr[1][0] << endl; cout << arr[0][5] << endl; cout << arr[9][5] << endl; }
Woher soll hier denn der Compiler wissen, wo arr[1] beginnt?
Wie ich schon sagte, er muss es nicht wissen. Es reicht, wenn die Adresse zur Laufzeit in arr[1] steht.
-
Also ich weiß nicht ob wir aneinander vorbeireden.
Was soll denn z.B. dieser Code bewirken?
double **Calc() { return (double **) malloc(sizeof(double *)); } int main() { double** arr= Calc(); arr[0][0] = 1; arr[1][0] = 2; }
-
Bashar schrieb:
Dass verschachtelte Arrays und Zeigerarrays beim Dereferenzieren gleich aussehen kann manchmal verwirrend sein ...
Ich glaube, langsam meinen Denkfehler zu verstehen...
-
Wow, wahnsinn!!
So viele Antworten in so kurzer Zeit...Danke erstmal, ich brauche jetzt wohl erst mal n bisschen Zeit um das alles zu verstehen...
Tausend Dank und Gruss
GierAffe
-
Javaner schrieb:
Was soll denn z.B. dieser Code bewirken?
Einen Absturz, weil arr[0] nicht initialisiert ist.