Speicherfehler am Anfang eines Vektors



  • Der erase-Befehl steht im Posting. Schreibe ihn aber gerne nochmal.
    Kann eigentlich kein zugriffsfehler sein, da ich den Zeiger auf begin() setze.

    result.trace(1).points().erase( result.trace(1).points().begin() );
    

    vector::_M_range_check

    und eine kleine Ergänzung der Funktion points()...

    class mTrace{
    public:
    ...
        /// returns the Points from the Trace
        std::vector<mPoint> points() const {return points_;};
        /// add a point to the trace
        void addPoint(const mPoint& pt){points_.push_back(pt);};
    private:
        int a_;
        int b_;
        std::vector<mPoint> points_;
    


  • Flaut schrieb:

    Kann eigentlich kein zugriffsfehler sein, da ich den Zeiger auf begin() setze.

    Sicher, dass der vector nicht leer ist?



  • Was gibt trace(1) zurück? Ist das ein Zugriff auf eine darüberliegende Datenstruktur oder sowas?

    Gruß Kimmi



  • points() gibt eine Kopie des Vektors zurück. Das erase wird auf einer anderen Kopie des Vektors aufgerufen als das begin.

    Gruss Chris



  • Stimmt, jetzt wo du es sagst :-). Fix wäre die Referenz auf points_ zurückzugeben. Allerdings darf die get-Methode dann nicht mehr const sein und sowas ist nicht gerade feier Stil.

    Gruß Kimmi



  • Dann gib der Klasse mTrace doch einfach ne Methode zum Point-Löschen 🙂



  • habe die löschen methode geschrieben, aber ich habe noch immer den gleichen Speicherfehler. Vermutlich, da es sich wieder um eine Kopie handelt?

    ...
    vector<mPoint>::iterator it = result.trace(1).points().begin();
    result.trace(1).remPoint( it );
    ...
    
    class mTrace{
    public:
    ...
        /// returns the Points from the Trace
        std::vector<mPoint> points() const {return points_;};
        /// remove a point from the trace
        void remPoint(const std::vector<mPoint>::iterator &pos){points_.erase(pos);};
        /// add a point to the trace
        void addPoint(const mPoint& pt){points_.push_back(pt);};
    private:
        int a_;
        int b_;
        std::vector<mPoint> points_;
    

    Aber das ist ja immer noch eine Korrektur, die ja das eigentliche Problem nicht löst. Denn das erste Element des Vektors variiert und dort sitzt der Unruhestifter.



  • Flaut schrieb:

    habe die löschen methode geschrieben, aber ich habe noch immer den gleichen Speicherfehler. Vermutlich, da es sich wieder um eine Kopie handelt?

    Ja, weil points() immernoch eine Kopie zurückliefert. Lasse points() eine konstante Referenz zurückliefern (oder eine nicht-konstante Referenz, aber dann brauchst Du remPoint() nicht mehr).

    Aber das ist ja immer noch eine Korrektur, die ja das eigentliche Problem nicht löst. Denn das erste Element des Vektors variiert und dort sitzt der Unruhestifter.

    Möchlich, dass das aus einer ähnlichen Situation herrührt - benutzt Du vielleicht irgendwo den Iterator einer Kopie als Einfügeposition für einen Vector?



  • Die Methode "remPoint" könnte auch einen Index entgegennehmen..



  • Wie kann ich denn die Referenz zurück geben? Ich kann doch in meiner Klasse keine Funktion schreiben, in der ich ein eigenes Element als Referenz bekomme? sonst bin ich wieder bei einer Kopie. Steh ich jetzt auf der Leitung? Ich muss doch auf meinen Vektor in der Klasse zugreifen können, ohne eine Kopie des Vektors, das ist ja auch sehr Speicherhungrig.

    und beim Ursprungsproblem nutze ich keinen Iterator. Ich lese mittels nodeToTrace ein, erzeuge mir dort eine Instanz vom Typ mTrace, setze die Werte und gebe die Instanz als Rückgabewert zurück.

    mTrace nodeToTrace(TiXmlElement* e) {
    
    	if (strcmp(e->Value(), "Trace") != 0)
    		throw runtime_error(string("wrong trace ") + e->Value());
    
    	mTrace result;
    	const char *traceID, *color, *numPoints;
    
    	//read Parameter
    	traceID = e->Attribute("traceID");
    	if (traceID != NULL)
    		result.setTraceID(atoi(traceID));
    	else
    		throw runtime_error(string("wrong traceID ") + e->Value());
    
    	color = e->Attribute("color");
    	if (color != NULL)
    		result.setColor(atoi(color));
    	else
    		throw runtime_error(string("wrong color ") + e->Value());
    
    	numPoints = e->Attribute("numPoints");
    	if (numPoints != NULL)
    		result.setNumPoints(atoi(numPoints));
    	else
    		throw runtime_error(string("wrong numPoints ") + e->Value());
    
    	if (result.points().empty()) {// TODO Speicherkorrektur
    		result.addPoint(mPoint(0, 0));
    	}
    
    	for (TiXmlElement* element = e->FirstChildElement(); element; element = element->NextSiblingElement()) {
    		result.addPoint(nodeToPoint(element));
    	}
    
    	return result;
    }
    

    Dies mache ich geschachtelt, aber immer auf die gleiche Weise readXML(mStructure(mTrace(mPoint()))).


Anmelden zum Antworten