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ötigt 🙄

    MfG 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


Anmelden zum Antworten