Memoryleak?



  • Hi, ich habe folgenden Code in der Hauptschleife platziert:

    for(unsigned int i=0; i<ShotVec.size(); i++)
    {
    	CShotVec::iterator it = ShotVec.begin();
    	it+= i;
    
    	ShotVec.at(i)->OnDraw();
    	ShotVec.at(i)->OnStep();
    	if(ShotVec.at(i)->GetY()<0)
    	{
    		delete *it;
    		ShotVec.erase(it);
    	}
    }
    

    Es geht darum, dass wenn das Objekt den y Wert kleiner als 0 hat, gelöscht wird. Das habe ich mir im Taskmanager beobachtet. Beim erstellen erhöht sich der zugewiesene Speicher um die Größe der Klasse, wird beim zerstören (s.o) aber nicht mehr gesenkt. Tritt hier ein Memoryleak auf?
    Das Problem ist auch, dass ich iterator nicht in int konvertieren kann.
    Wozu? Naja ShotVec.at(); arbeitet nunmal mit int aber ich kann leider nicht ShotVec.erase(); mit int benutzen, obwohl das sehr gut wäre, weil ich das direkt aus der for-schleife nehmen könnte.

    Vielen Dank schon mal
    mfg Critical



  • Mehr Code wäre gut...

    for(it = ShotVec.begin(); it != ShotVec.end(); ++it) 
    {
    	it->OnDraw();
    	it->OnStep();
    
    	if(it->GetY() < 0) 
    		ShotVec.erase(it);
    }
    

    😕



  • Critical schrieb:

    it+= i;
    

    Hier gehst du mit dem Iterator immer soviele Stellen vorwärts, wie i gerade ist, nicht immer eine!

    Edit: Sorry, stimmt natürlich nicht. Ich hab die Initialisierung gerade darüber nicht gesehen. Dennoch könntest du gerade CShotVec::iterator it = ShotVec.begin() + i; schreiben.

    Aber du kannst es auch einfacher machen, wenn du keine Iteratoren als Zählvariabeln haben willst:

    ShotVec.erase(ShotVec.begin() + i);
    

    Wobei du aufpassen musst, dass i entsprechend angepasst werden muss, weil ja dann ein Element weniger vorkommt. Sprich:

    i--;
    


  • So ich habe das jetzt mal überarbeitet:

    for(unsigned int i=0; i<ShotVec.size(); i++)
    {
    	ShotVec.at(i)->OnDraw();
    	ShotVec.at(i)->OnStep();
    
    	if(ShotVec.at(i)->GetY()<0)
    	{
    		ShotVec.erase(ShotVec.begin() + i);
    		i--;
    	}
    }
    

    So sollte das richtig sein. Auf jedenfall bleibt der Speicher gleich und geht nicht konsequent in die Höhe. Danke! 🙂
    Jetzt noch ne Frage: Wenn ich ShotVec.erase(); aufrufe, wird dann auch die Instanz von CShot zerstört? Also sozusagen ein delete durchgeführt?



  • Das Problem hatte ich auch schon mal.
    Wenn im Vektor ein Element gelöscht wird, dann werden die folgenden Elemente alle um eins nach vorne geschoben. Das heisst, es wird einige Male eine Zuweisung (mit 🙂 durchgeführt und jedes Element von dem zu löschenden an wird mit dem nächstfolgenden überschrieben (Mit "löschen" meine ich erase() auf eine Stelle ausführen). Das letzte Element, bzw. die Instanz an der letzten Stelle, wird dann destruiert.
    Besonders mühsam wird es, wenn du keine einfache Klasse mehr hast, sondern darin Zeigervariabeln vorkommen. Dann kannst du dich nämlich mit Kopierkonstruktor, überladenem Zuweisungsoperator und Destruktor (die "Grossen Drei") beschäftigen...

    Ach ja, und am Anfang hattest du ein delete geschrieben. Ich denke nicht, dass das bei Iteratoren überhaupt zulässig ist, da diese eigentlich wie Stackvariabeln gehandhabt werden und du sie auch nicht mit new erzeugt hast. Wenn schon, dann müsstest du

    delete it;
    

    anstelle von

    delete *it;
    

    schreiben. Wenn du jedoch ein erase() hast, ist das delete sowieso überflüssig.



  • In dem vector scheinen aber Pointer zu sein. Da ist erstens delete *it; schon richtig und zweitens ein delete auch notwendig, wenn du das nicht irgendwo anders machst.



  • Braunstein schrieb:

    In dem vector scheinen aber Pointer zu sein. Da ist erstens delete *it; schon richtig und zweitens ein delete auch notwendig, wenn du das nicht irgendwo anders machst.

    Sorry, ich habe die -> nicht weiter beachtet... Ich sollte mal den Code genauer anschauen. 😉

    Wenn die Vektorelemente mit new initialisiert wurden, sollte man das delete schon ausführen. Aber was macht dann erase() ? Erkennt es den Pointer und löscht automatisch die Instanz, die man beim Dereferenzieren des Iterators erhält?


Anmelden zum Antworten