Rückgabe eines verschachtelten std::vector aus Funktion



  • Ich habe eine Klasse, die intern Koordinaten mit Hilfe des folgenden Typs vvvfloat speichert:

    typedef vector<float> vfloat;
    typedef vector<vfloat> vvfloat;
    typedef vector<vvfloat> vvvfloat;
    

    Nun biete ich zum Auslesen folgende Methode an:

    vfloat GetPoint(int x, int y);
    

    So, wie ich es bisher versucht habe, bekomme ich nur uninitialisierte Werte nach dem Aufruf ausgegeben.

    So rufe ich die Funktion auf:

    for (int i = 0; i < pointCount[0]; i++) {
    	for (int j = 0; j < pointCount[1]; j++) {
    		vfloat point = surface->GetPoint(i, j);
    		cout << "Point (" << i << ", " << j << "): " << point[0] << ", "
    				<< point[1] << ", " << point[2] << endl;
    	}
    }
    

    Zur Kontrolle lasse ich in der Funktion selbst ebenfalls die Werte ausgeben, dort werden sie richtig ausgegeben.

    Folgende Varianten habe ich bereits versucht, keine funktioniert. Wer kann mir helfen?

    vfloat SurfaceConfiguration::GetPoint(int x, int y) {
    	cout << "Point (" << x << ", " << y << "): " << this->points[x][y][0] << ", "
    			<< this->points[x][y][1] << ", " << this->points[x][y][2] << endl;
    	return this->points[x][y];
    }
    
    vfloat SurfaceConfiguration::GetPoint(int x, int y) {
    	cout << "Point (" << x << ", " << y << "): " << this->points[x][y][0] << ", "
    			<< this->points[x][y][1] << ", " << this->points[x][y][2] << endl;
    	vfloat point = this->points[x][y];	
    	return point;
    }
    
    vfloat SurfaceConfiguration::GetPoint(int x, int y) {
    	cout << "Point (" << x << ", " << y << "): " << this->points[x][y][0] << ", "
    			<< this->points[x][y][1] << ", " << this->points[x][y][2] << endl;
    	vfloat point(this->points[x][y]);	
    	return point;
    }
    

    Danke schon einmal für Eure Hilfe!



  • Wie füllst Du denn die Vektoren bzw. mit welcher Größe initialisierst Du sie?
    Probier mal das:

    return points.at(x).at(y);
    

    Wenn Du da eine Exception bekommst, dann ist Dein Vektor für die Idizes nichtmal initialisiert.



  • Die Werte werden aus einer Datei gelesen, in der pro Zeile drei Zahlen stehen, je durch ein Komma getrennt.

    Sollte im Prinzip aber irrelevant sein, da die Ausgabe der Punkte innerhalb der Klasse ja richtig funktioniert.

    Der Vollständigkeit halber hier der Code:

    void SurfaceConfiguration::loadPoints() {
    	ifstream pointsFile("points.gen");
    	char buffer[100]; // just to make sure the whole line fits in
    
    	int length = pointCount[0];
    	int width = pointCount[1];
    	points.resize(length);
    	for (int i = 0; i < length; i++) {
    		this->points[i].resize(width);
    		for (int j = 0; j < width; j++) {
    			points[i].resize(width);
    
    			// read and split line
    			pointsFile.getline(buffer, sizeof(buffer));
    			vector<string> thisPoint = explode(buffer, ",");
    
    			for (int k = 0; k <= 2; k++) {
    				istringstream(thisPoint[k]) >> this->points[i][j][k];
    				//cout << "Point (" << i << ", " << j << ")[" << k << "]: " << this->points[i][j][k] << endl;
    			}
    		}
    	}
    }
    

    Edit:

    return points.at(x).at(y);
    

    ist doch das gleiche wie

    return points.[x][y];
    

    oder nicht?

    Das Ergebnis unterscheidet sich jedenfalls nicht.



  • vector.at(index)
    

    Prüft seine Grenzen und wirft eine Exception, wenn man versucht über sie hinaus zu lesen.

    vector.operator[](index)
    

    Prüft hingegen seine Grenzen nicht und erlaubt so, auf nicht allokierten Speicher zuzugreifen.



  • Argh, ich bin doof!!

    Zeile 11 macht den Unterschied:

    Falsch:

    void SurfaceConfiguration::loadPoints() {
        ifstream pointsFile("points.gen");
        char buffer[100]; // just to make sure the whole line fits in
    
        int length = pointCount[0];
        int width = pointCount[1];
        points.resize(length);
        for (int i = 0; i < length; i++) {
            this->points[i].resize(width);
            for (int j = 0; j < width; j++) {
                points[i].resize(width);
    
                // read and split line
                pointsFile.getline(buffer, sizeof(buffer));
                vector<string> thisPoint = explode(buffer, ",");
    
                for (int k = 0; k <= 2; k++) {
                    istringstream(thisPoint[k]) >> this->points[i][j][k];
                    //cout << "Point (" << i << ", " << j << ")[" << k << "]: " << this->points[i][j][k] << endl;
                }
            }
        }
    }
    

    Richtig:

    void SurfaceConfiguration::loadPoints() {
    	ifstream pointsFile("points.gen");
    	char buffer[100]; // just to make sure the whole line fits in
    
    	int length = pointCount[0];
    	int width = pointCount[1];
    	points.resize(length);
    	for (int i = 0; i < length; i++) {
    		this->points[i].resize(width);
    		for (int j = 0; j < width; j++) {
    			this->points[i][j].resize(3);
    
    			// read and split line
    			pointsFile.getline(buffer, sizeof(buffer));
    			vector<string> thisPoint = explode(buffer, ",");
    
    			for (int k = 0; k <= 2; k++) {
    				istringstream(thisPoint[k]) >> this->points[i][j][k];
    			}
    		}
    	}
    }
    

    Hätte ich eigentlich eher sehen müssen, aber naja, jedenfalls dennoch danke, tachyon, für die Belehrung!

    Problem gelöst!


Anmelden zum Antworten