Zeiger auf Vector - ich kapiers einfach nicht...
-
Hallo,
Ich will einer Funktion einen Zeiger auf einen 2D-Vector übergeben und dann auf die einzelnen Werte des Vectors zugreifen. Wie mache ich das?
So jedenfalls nicht:
//--------------------------------------------------------------------------- #include <vector.h> #include <stdio.h> #pragma hdrstop //--------------------------------------------------------------------------- void kennfeld(vector<vector<double> > *kennfeld_ptr); vector<vector<double> > kennfeld_v; //--------------------------------------------------------------------------- #pragma argsused int main(int argc, char* argv[]) { kennfeld_v.clear(); vector<double> line; line.clear(); // Vector mit Dummy-Daten füllen for(int i = 0; i < 5; i++) line.push_back(3.3); for(int i = 0; i < 10; i++) kennfeld_v.push_back(line); // Funktion aufrufen kennfeld(&kennfeld_v); } //---------------------------------------------------------------------------- void kennfeld(vector<vector<double> > *kennfeld_ptr) { double test = kennfeld_ptr[3][4]; printf("%d\n", test); }
Da gibts die nette Fehlermeldung:
[C++ Fehler] Unit1.cpp(34): E2034 Konvertierung von 'vector<double,allocator<double> >' nach 'double' nicht möglich
Zeiger habe ich noch nie kapiert....
Kann mir jemand sagen was hier schief läuft und wie es richtig gehen würde?
Danke!
-
Wozu benötigst du denn hier Zeiger?
[cpp]
#include <iostream>
#include <vector>
using namespace std;// Besser wäre wohl const vector<vector<double> >& vec
// da dann nur eine referenz übergeben wird und keine kopie der daten gemacht werden muss
void output (const vector<vector<double> > vec)
{
for(int i = 0; i < vec.size(); ++i)
for(int j = 0; j < vec[i].size(); ++j)
cout << i << "/" << j << ": " << vec[i][j] << endl;
}int main ()
{
vector<vector<double> > myVec; // zweidimensionaler Vektor// Mit Testdaten füllen
for(int i = 0; i < 10; ++i)
{
myVec.push_back(vector<double>());
for(int j = 0; j < 10; ++j)
myVec.push_back(3.3);
}// Funktion aufrufen
output(myVec);return 0;
}
[/cpp]
Wie du sihest habe ich keinen einzigen Zeiger benötigtMfG SideWinder
-
zeigerfreund schrieb:
Hallo,
Ich will einer Funktion einen Zeiger auf einen 2D-Vector übergeben und dann auf die einzelnen Werte des Vectors zugreifen. Wie mache ich das?
So jedenfalls nicht:
//--------------------------------------------------------------------------- #include <vector.h> // <vector> nicht <vector.h> #include <stdio.h> #pragma hdrstop //--------------------------------------------------------------------------- void kennfeld(vector<vector<double> > *kennfeld_ptr); // warum als Zeiger übergeben? vector<vector<double> > kennfeld_v; // wenn eh global, wozu überhaupt übergeben? //--------------------------------------------------------------------------- #pragma argsused int main(int argc, char* argv[]) { kennfeld_v.clear(); // wurde nie gefüllt, wozu also leeren? vector<double> line; line.clear(); // wurde erst recht nicht gefüllt // Vector mit Dummy-Daten füllen for(int i = 0; i < 5; i++) // sieht nach einem fall für std::fill aus line.push_back(3.3); for(int i = 0; i < 10; i++) // dito kennfeld_v.push_back(line); // Funktion aufrufen kennfeld(&kennfeld_v); } //---------------------------------------------------------------------------- void kennfeld(vector<vector<double> > *kennfeld_ptr) { double test = kennfeld_ptr[3][4]; // zeiger dereferenzieren nicht vergessen!!! die [3] bezieht sich auf deinen (sinnlosen) Zeiger printf("%d\n", test); }
Da gibts die nette Fehlermeldung:
[C++ Fehler] Unit1.cpp(34): E2034 Konvertierung von 'vector<double,allocator<double> >' nach 'double' nicht möglich
Zeiger habe ich noch nie kapiert....
Kann mir jemand sagen was hier schief läuft und wie es richtig gehen würde?
-
Ist klar.
Aber die 1500 Zeilen Code, welche den Zeiger nötig machen, wollte ich jetzt nicht posten. Deshalb habe ich die Sache eingedampft und ein dummes Testprogramm draus gemacht.
-
Ich kann mir aber auch sonst keine Echt-Situation ausdenken in denen du den Vektor nicht besser per Referenz übergibst...
MfG SideWinder
-
Der einzige Grund, der mir momentan einfällt, der diese bekloppte Signatur nötig machen würde wäre, wenn due vorhast die Funktion per Funktionszeiger an eine andere Funktion zu übergeben und du hast diese Funktion nicht selbst geschrieben.
Zwar möglich, aber IMHO unwarscheinlich.Außerdem musst du ja nicht den Code posten, sondern kannst in zwei drei Sätzen erklären, warum es nötig ist.
-
Ich hab das Beispiel mal ausgebaut:
//--------------------------------------------------------------------------- #include <vector.h> #include <stdio.h> #include <conio.h> #pragma hdrstop //--------------------------------------------------------------------------- void kennfeld_funkt(vector<vector<double> > kennfeld_ptr); //--------------------------------------------------------------------------- #pragma argsused int main(int argc, char* argv[]) { vector<vector<double> > kennfeld; kennfeld.clear(); vector<double> line; line.clear(); // Dummy-Daten for(int i = 0; i < 5; i++) line.push_back(3.3); for(int i = 0; i < 10; i++) kennfeld.push_back(line); // Funktionsaufruf kennfeld_funkt(kennfeld); // Testausgabe double test = kennfeld[3][4]; printf("%f\n", test); getch(); } //---------------------------------------------------------------------------- void kennfeld_funkt(vector<vector<double> > kennfeld_ptr) { // Testausgabe double test = kennfeld_ptr[3][4]; printf("%f\n", test); getch(); vector<double> line; line.clear(); // Dummy-Daten ersetzen for(int i = 0; i < 5; i++) { for(int j = 0; j < 10; j++) kennfeld_ptr[i][j] = 435.324; } // Testausgabe test = kennfeld_ptr[3][4]; printf("%f\n", test); getch(); }
Das Problem ist, dass die Funktion die Werte der übergebenen Vectoren ändern muß.
Das geht mit SideWinders Code leider nicht.
-
Fehlende * und & bitte ergänzen...
Jetzt müsste alles da sein://--------------------------------------------------------------------------- #include <vector.h> #include <stdio.h> #include <conio.h> #pragma hdrstop //--------------------------------------------------------------------------- void kennfeld_funkt(vector<vector<double> > *kennfeld_ptr); //--------------------------------------------------------------------------- #pragma argsused int main(int argc, char* argv[]) { vector<vector<double> > kennfeld; kennfeld.clear(); vector<double> line; line.clear(); // Dummy-Daten for(int i = 0; i < 5; i++) line.push_back(3.3); for(int i = 0; i < 10; i++) kennfeld.push_back(line); // Funktionsaufruf kennfeld_funkt(&kennfeld); // Testausgabe double test = kennfeld[3][4]; printf("%f\n", test); getch(); } //---------------------------------------------------------------------------- void kennfeld_funkt(vector<vector<double> > *kennfeld_ptr) { // Testausgabe double test = kennfeld_ptr[3][4]; printf("%f\n", test); getch(); vector<double> line; line.clear(); // Dummy-Daten ersetzen for(int i = 0; i < 5; i++) { for(int j = 0; j < 10; j++) kennfeld_ptr[i][j] = 435.324; } // Testausgabe test = kennfeld_ptr[3][4]; printf("%f\n", test); getch(); }
Sorry
-
zeigerfreund schrieb:
Das Problem ist, dass die Funktion die Werte der übergebenen Vectoren ändern muß.
#include <iostream> #include <vector> using namespace std; void aendere(vector<double> &vec) { vec[0] = 3.1415; } int main() { vector<double> geht_ohne_zeiger; geht_ohne_zeiger.push_back(3.14); cout << geht_ohne_zeiger[0] << endl; aendere(geht_ohne_zeiger); cout << geht_ohne_zeiger[0] << endl; cin.get(); }
-
OK, so gehts. Vielen Dank.
Hat mal jemand ein Snickers für mich?
Was sind denn die grundsätzlichen Probleme, wegen der ihr von Zeigern abratet?
Bzw. geht das hier mit Zeigern gar nicht?
-
Zeiger sind halt unsicherer, weil es leicht vorkommen kann, dass sie auf ungültigen Speicher zeigen. Wenn man brav aufpasst, ob der Speicher nicht zwischenzeitlich freigegeben wurde (dann kann er sogar bereits woanders zugeteilt worden sein) oder ob der Zeiger nicht falsch verschoben wurde, oder, oder, oder, geht es auch damit, aber wozu soll man sich das Leben schwer machen. Dennoch hier ein Beispiel:
#include <iostream> #include <vector> using namespace std; void aendere_mittels_zeiger(vector<vector<double> > *v) { (*v)[0][0] = .2; } int main() { vector<vector<double> > vec; vec.push_back(vector<double>()); vec[0].push_back(.1); cout << vec[0][0] << endl; aendere_mittels_zeiger(&vec); cout << vec[0][0] << endl; cin.get(); }
-
Achso:
referenzenfreund schrieb:
(*v)[0][0] = .2;
(*v) Jetzt wird mir einiges klar!
Danke!
-
Um mal meine erste Antwort zu zitieren:
ich selbst schrieb:
double test = kennfeld_ptr[3][4]; // zeiger dereferenzieren nicht vergessen!!! die [3] bezieht sich auf deinen (sinnlosen) Zeiger