vector < vector <float> > nachträglich initalisieren



  • Danke SeppJ, wenn ich die Zuweisung durch

    V[a=0].push_back(b)
    

    ersetze, bekomme ich einen Fehler beim Ausführen auf die Zeile. Im eindimsionalen Vektorfall

    V.push_back(a)
    

    funktioniert es.

    Was ich für mein Programm benötige ist, dass ich - wie mit einen normalen Array - einen spezifischen Wert in V[a][b] sowohl setzen als auch lesen kann.

    Rein theoretisch könnte ich natürlich über "Umwege" erstmal den Vektor an mit allen entsprechenden Inhalten des Arrays b befüllen. Aber dann könnte ich Vektoren ja gleich umgehen....





  • meinst du damit, dass ich meinen vollständigen Code posten soll oder das ich einfach höflich um ein Codebeispiel bitten soll? 😕

    Einen Compilerfehler schließe ich aus, da das Programm ja kompilliert wird, und dann beim Ausführen abbricht.



  • Weder, noch. Aber das steht ja alles in dem Link.



  • okay 🙄 let´s try:

    Meine Klasse:

    class Plate	{
    	int fields;
    	vector<vector<float> > absorb;
    
    	public:
    		Format* format = bookOut->addFormat();
    		Font* font = bookOut->addFont();
    		void set_plate(int wave, int field_num);
    		void setField(int wave, int field, float density);
    		float getField(int wave, int field);
    		Format* set_format(int num);
    };
    

    Mein "Konstruktor" ..ich weiß eigentlich eine Klassenfunktion.

    void Plate::set_plate(int wave, int field_num)	{
    	absorb.resize(wave);
    	//for (int i = 0; i < wave; ++i)	{	absorb.reserve(field_num);	}
    };
    

    Die zu nutzenden Funktionen:
    [i] absorb[wave].push_back(density); steht in Zeile 75 *

    void Plate::setField(int wave, int field, float density)	{
    	//absorb[wave][field] = density;
    	absorb[wave].push_back(density);
    
    };
    
    float Plate::getField(int wave, int field)	{
    	return	absorb[wave][field];
    };
    

    Und der Aufruf der fehlschlägt in meiner main():

    P[current_plate].setField(i, 0, sheetIn->readNum(row+3, col+2));
    

    Wobei current_Plate = (int) 0, i = 0 und sheetIn->readNum(row+3, col+2) ein float Wert.

    Ich hoffe das reicht, um mein Problem nachzuvollziehen. Die Fehlermeldung hatte ich bereits im Post drüber beschrieben. Genau lautet diese (Ablaufverfolgung):

    std::vector<float, std::allocator<float> >::push_back(this = 0x0, __x = @0x29f3f8: 0.0549999997) C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++/bits/stl_vector.h 915

    Plate::setField(this = 0x29f40c, wave = 0, field = 0, density = 0.0549999997) main_template.cpp 75



  • Den Code kann ich jetzt ja immer noch nicht selbst compilieren um den Fehler nachzustellen. In der main Funktion wird aber schon vorher mal set_plate mit der richten Größe aufgerufen?



  • Genau, Instanzen von Plate wird erzeugt.

    Plate P[plates_num];
    

    Das Ding ist, dass der Code vorher lief, bevor ich die float Arrays durch Vektoren ersetzt habe.

    D.h. im Grunde bräuchte ich nur eine Hilfe, wie ich richtig mit mehrdimensionalen Vektoren arbeite (der Code an sich ist korrekt). Mit eindimensionalen Vektoren habe ich wie gesagt kein Problem. Falls Ihr mir das hier nicht erklären könnt und Ihr mir stattdessen einen guten Link zu einer Eklärung geben könnt, wäre ich Euch auch dankbar. Ich finde leider nur etwas über eindimensionale Probleme und bei meinen Versuch dieses auf mehrdimensionale Vektoren anzuwenden scheitere ich 😞



  • Die Funktion push_back wird für einen nicht existierenden Vector aufgerufen (this ist ein Nullpointer). Das ist plausibel, denn wenn du absorb.resize(wave) aufrufst, ist absorb[wave] natürlich ungültig.



  • tillt schrieb:

    Genau, Instanzen von Plate wird erzeugt.

    Plate P[plates_num];
    

    Und wird jetzt set_plate irgendwo aufgerufen? Dadurch, dass du ein Array anlegst passiert das jedenfalls nicht.

    tillt schrieb:

    Das Ding ist, dass der Code vorher lief, bevor ich die float Arrays durch Vektoren ersetzt habe.

    Das ist leider keine Garantie dafür, dass der Code vorher fehlerfrei war. Vielleicht hast du auch wild irgendwas im Speicher überschrieben und es war einfach Glück, dass es nicht abgestürzt ist.

    Zweidimensionale Arrays mit vector funktionieren genauso wie eindimensionale. Wenn du endlich mal ein vollständiges (für das Problem irrelevante Teile weglassen) und compilierbares Codebeispiel zu deinem Problem lieferst, dann findet einer der Experten hier den Fehler sicher in Rekordzeit.


  • Mod

    Man sollte noch erwähnen, dass ein verschachtelter Vector nicht der Datenstruktur entspricht, die man im allgemeinen als 2D-Array bezeichnet. Ein 2D-Array wäre offensichtlich ein Array von Arrays, kein Vector von Vectoren. Oder auch ein Vector von Arrays, der auch das gleiche Layout hätte wie ein Array von Arrays.

    Dieses Missverständnis scheint, neben allgemeiner Unkenntnis von Vectoren, eine der Ursachen des Problems zu sein. Vectoren haben eben die Eigenschaft flexibler Größe, Arrays nicht. Was dazu führt, dass ein leerer Vector wirklich leer ist. Da ist absolut nichts drin, nicht einmal leerer Platz.



  • Vielen Dank für eure Tipps! Ich habe jetzt ein Minimalbeispiel meines Problems erstellt und hoffe ihr könnt mir so besser meine Fehler aufzeigen.

    #include <cstdlib>
    #include <stdlib.h>
    #include <stdio.h>
    #include <iostream>
    #include <math.h>
    #include <vector>
    
    using namespace std;
    
    class testclass	{
    
      public:
    
            vector<vector<float> > matrix;
    
    		void set_matrix(int rows, int cols);
    		void setField(int row, int col, float value);
    		float getField(int row, int col);
    
    };
    
    void testclass::set_matrix(int rows, int cols)	{
      matrix.reserve(rows);
      for (int i = 0; i < rows; ++i)	{	matrix[i].reserve(cols);	}
    };
    
    void testclass::setField(int row, int col, float value)	{
    	// okay, hier wird erstmal col nicht benötigt
    	matrix[row].push_back(value);
    };
    
    float testclass::getField(int row, int col)	{
    	return	matrix[row][col];
    };
    
    int main(int argc, char *argv[])	{
    
    	int copys = 38;
    	testclass P[copys];
    	int rows=2;
    	int cols=96;
    
    	for (int j=0; j < copys; j++)	{	P[j].set_matrix(rows, cols);		}
    
    	for ( int j = 0; j < copys; j++)	{
    		for ( int i = 0; i < rows; i++)	{
    			P[j].setField(i, 0, 5.00);
    			P[j].getField(i, 0);
    		}
    	}
    }
    

    Grob gesagt möchte ich Vektoren von float Vektoren in einer Klasse während des Hauptprogramms setzen und lesen. Wobei die Größe beim Erstellen der Klasseninstanzen noch nicht bekannt ist.


  • Mod

    Hast du irgendeine der Antworten in diesem Thread gelesen? Du machst doch immer noch reserve, wo resize angebracht wäre. Außerdem traf meine Spekulation weiter oben voll ins Schwarze: Ein vector<vector<float>> ist keine gute Datenstruktur für eine mathematische Matrix. Besser wäre hier einfach ein ganz normaler vector<float>. Als Anpassung deines Programm ginge das so (ungetestet gegen Tippfehler und sonstiges):

    class testclass {
    
      public:
    
            vector<float> matrix;
            unsigned num_rows, num_cols;
            void set_matrix(int rows, int cols);
            void setField(int row, int col, float value);
            float getField(int row, int col);
    
    };
    
    void testclass::set_matrix(int rows, int cols)  {
      num_rows = rows; num_cols = cols;
      matrix.resize(num_rows * num_cols);
    };
    
    void testclass::setField(int row, int col, float value) {
        // Natürlich wird hier col benötigt. Fällt dir das nicht als Logikfehler beim Programmieren auf, dass das nicht sein kann, dass du ein Matrixelement ohne Spaltenindex adressieren willst?
        matrix[row * num_cols + col] = value;
    };
    
    float testclass::getField(int row, int col) {
        return  matrix[row * num_cols + col];
    };
    


  • Danke SeppJ,

    das eindimsionale Beispiel von dir läuft gut. Auch wenn dies die bessere Lösung ist, möchte ich gerne verstehen, wie ich es im Falle eines vector < vector < float> > lösen kann.
    In meinen Beispielcode hatte ich auch schon reserve durch resize ausgetauscht (sorry! Komischerweise hält das Programm in der letzten Schleife bei mehr Elementen durch (Programmabsturz), wenn ich reserve statt resize benutze!?).
    Ich denke mein Fehler liegt darin, dass ich die "cols" auch "resizen" möchte...

    #include <cstdlib>
    #include <stdlib.h>
    #include <stdio.h>
    #include <iostream>
    #include <math.h>
    #include <vector>
    
    using namespace std;
    
    class testclass	{
    
    	public:
            int col;
            vector<vector<float> > matrix;
    
    		void set_matrix(int rows, int cols);
    		void setField(int row, int col, float value);
    		float getField(int row, int col);
    
    };
    
    void testclass::set_matrix(int rows, int cols)	{
      matrix.resize(rows);
      for (int i = 0; i < rows; ++i)	{	matrix[i].resize(cols);	}
    };
    
    void testclass::setField(int row, int col, float density)	{
    	// okay, hier wird erstmal col nicht benötigt - da ich ja mit push_back nur in die Reihe direkt ans Ende schreibe!
    	//matrix[row].push_back(density);
    	matrix[row][col] = density;
    };
    
    float testclass::getField(int row, int col)	{
    	return	matrix[row][col];
    };
    
    int main(int argc, char *argv[])	{
    
    	int copys = 38;
    	testclass P[copys];
    	int rows = 2;
    	int cols = 96;
    	int num = 0;
    
    	for (int j=0; j < copys; j++)	{	P[j].set_matrix(rows, cols);		}
    
    	for ( int j = 0; j < copys; j++)	{
    		for ( int i = 0; i < cols; i++)	{
                for ( int k = 0; k < rows; k++)	{
                    P[j].setField(i, k, num);
                    num++;  cout << "\n" << P[j].getField(i, k);
                }
            }
        }
    }
    

    Aber wenn ich nur matrix.resize(rows) anwende bekomme ich nach einigen Elementen einen Programmabbruch, weshalb ich davon ausgehe, dass es zu Speicherüberschneidungen der einzelnen Reihen kommt, da nicht genügend Speicher für die Spaltenelemente matrix[row] = c1, ..., cn vorhanden ist.
    Aber wie kann ich die "gesamte" Größe einer Reihe richtig setzen? Mit matrix.resize(row*cols) geht es auch nicht.
    Bitte entschuldige, wenn ich immer noch Denkfehler mache!



  • tillt schrieb:

    Aber wenn ich nur matrix.resize(rows) anwende bekomme ich nach einigen Elementen einen Programmabbruch, weshalb ich davon ausgehe, dass es zu Speicherüberschneidungen der einzelnen Reihen kommt, da nicht genügend Speicher für die Spaltenelemente matrix[row] = c1, ..., cn vorhanden ist.
    Aber wie kann ich die "gesamte" Größe einer Reihe richtig setzen? Mit matrix.resize(row*cols) geht es auch nicht.
    Bitte entschuldige, wenn ich immer noch Denkfehler mache!

    "Wenn ich Hufe höre, denke ich an Pferde."

    Warum testest Du nicht erstmal, ob Deine Zugriffe alle innerhalb der Grenzen liegen?
    Ein einfaches if... genügt. Stattdessen ergibst Du dich in wilden Vermutungen.



  • Du hast cols und rows vertauscht. Wenn du die Klasse unverändert lässt müsste die Schleife so aussehen:

    for (int i = 0; i < rows; i++) {
      for (int k = 0; k < cols; k++) {
        P[j].setField(i, k, num);
        num++;  cout << "\n" << P[j].getField(i, k);
      }
    }
    


  • Okay 😃
    Vielen Dank euch allen - ich denke ich habe jetzt alle (meine 🤡 ) Fehler eliminiert.


Anmelden zum Antworten