Crash mit boost::ptr_vector
-
class NLRenderManager { typedef boost::ptr_vector<NLAnimation*> NLAnimationList; //......... } void NLRenderManager::onRender(const u32 delta) { //............... for ( size_t i = 0; i < m_animationList.size(); i++ ) { NLAnimation* obj = m_animationList[i]; obj->renderObject(); // <- crasht hier obj->update(delta); } }Selber Code mit std::vector funktioniert tadellos.
First-chance exception at 0x655f3cb5 (NightLightDLL-d.dll) in NLSandbox-d.exe: 0xC0000005: Access violation reading location 0x46e8f43f.
Unhandled exception at 0x655f3cb5 (NightLightDLL-d.dll) in NLSandbox-d.exe: 0xC0000005: Access violation reading location 0x46e8f43f.Wie man am Bild sieht, scheint auch der Member m_frame nicht mehr vorhanden zu sein... bzw der Speicher dazu fehlt.
http://img340.imageshack.us/img340/1463/debugger.jpg
rya.
-
Naja, ein pointer_vector auf Pointer ist nicht wirklich sinnvoll. Muss du hier wirklich einen vector von Pointern auf Pointer speichern?
Phil
-
Meiner Meinung nach sollte es
boost::ptr_vector<NLAnimation>heißen. Als Template-Argument verwendest du dann den Datentyp selbst und nicht einen Zeiger darauf - die Elemente von ptr_vector sind dann Zeiger auf Objekte diesen Typs (und nicht Zeiger auf Zeiger auf Objekte). Wo wäre sonst der Unterschied zuboost::vector<NLAnimation*>?
-
Ich habe den Eindruck, dass es da einige Missverständnisse Deinerseits gibt. Lies Dir nochmal durch, wozu boost::ptr_vector gut ist und wie man ihn benutzt. Ich finde es auch komisch, dass Du std::vector<T*> mit boost::ptr_vector<T*> vergleichst.
Zeig dochmal, wie Du den Vektor füllst.
-
Okay, also so geht es:
class NLRenderManager { typedef boost::ptr_vector<NLAnimation> NLAnimationList; //......... } void NLRenderManager::onRender(const u32 delta) { //............... for ( size_t i = 0; i < m_animationList.size(); i++ ) { NLAnimation& obj = m_animationList[i]; obj.renderObject(); obj.update(delta); } }Die Doku gibt leider zu der Klasse nicht viel her. Deswegen war ich hier etwas verwirrt.
@KK
Gefüllt wird der Vector mit Zeigern auf Objekte die auf dem Heap liegen, also mit new erzeugt wurden. Ich habe dazu in ##c++ auf freenode gefragt, was mir hier helfen könnte, dass ich die ganzen objekte nicht ständig beim zerstören mit delete durchlaufen muss. Das ist so gewollt, da die Klasse NLRenderManager den Besitz dieser Objekte übernimmt. Ich dachte erst an auto_ptr aber die gehen ja nicht in vector. Mir wurde dann ptr_vector empfohlen, da dieser genau dieses Verhalten hat.
So meine Idee und Überlegung.
rya.
-
Scorcher24 schrieb:
@KK
Gefüllt wird der Vector mit Zeigern auf ObjekteDas ist mir zu ungenau. Es beantwortet meine Frage nicht. Aber Dein Problem hat sich ja anscheinend erledigt.
-
krümelkacker schrieb:
Scorcher24 schrieb:
@KK
Gefüllt wird der Vector mit Zeigern auf ObjekteDas ist mir zu ungenau. Es beantwortet meine Frage nicht. Aber Dein Problem hat sich ja anscheinend erledigt.
Das Problem ja, aber was genau möchtest Du denn wissen?
Ein Anwendungsbeispiel:// ---------------------------------------- // Create Animation // ---------------------------------------- NLAnimation* anim = new NLAnimation("Munchkin"); for ( int i = 1; i <= 4; i ++ ) { std::stringstream framename; framename << "Frame" << i; std::stringstream texname; texname << "f" << i; NLAnimationFrame* f = new NLAnimationFrame(i, NLVector2f(300.0f,300.0f), NLVector2f(100.0f,100.0f), NLVector2f(0.0f,0.0f), NLLayerConstants::MAP_DETAIL, framename.str().c_str()); f->setTexture(g_resGrp, texname.str().c_str()); f->setBlending(true); anim->addFrame(f); } anim->setAnimationFps(4); anim->startAnimation(); renderMgr.add(anim);.add fügt die Animation über push_back hinzu.... oder auch:
NLQuad* background = new NLQuad(SystemController().getWindow().getSettings().getSizef(), NLVector2f(0.0f,0.0f), NLVector2f(0.0f,0.0f), NLLayerConstants::BACKGROUND, "Background"); background->setTexture(g_resGrp, "Background"); background->setBlending(false); renderMgr.add(background);Beantwortet das die Frage?

Ansonsten formulier sie doch bitte anders.. steh iwie aufm Schlauch.edit:
Aber in der Doku steht:
The most important aspect of a pointer container is that it manages memory for you. This means that you in most cases do not need to worry about deleting memory.
http://www.boost.org/doc/libs/1_33_1/libs/ptr_container/doc/tutorial.html
Und genau das ist doch, was ich möchte...
rya.
-
Scorcher24 schrieb:
.add fügt die Animation über push_back hinzu....
Und genau diesen Code hätte ich sehen wollen.
Denn folgendes funzt einfach nicht:
boost::ptr_vector<int*> schwachfug; schwachfug.push_back(new int);Aber anscheinend hast Du irgendwas anderes gemacht, was sich kompilieren ließ.
Scorcher24 schrieb:
Und genau das ist doch, was ich möchte...
Ja dann ist ja gut. :p
-
krümelkacker schrieb:
Scorcher24 schrieb:
.add fügt die Animation über push_back hinzu....
Und genau diesen Code hätte ich sehen wollen.
Denn folgendes funzt einfach nicht:
boost::ptr_vector<int*> schwachfug; schwachfug.push_back(new int);Aber anscheinend hast Du irgendwas anderes gemacht, was sich kompilieren ließ.
Eh... das wäre ja dummfug in meinem context.

void NLRenderManager::add( NLAnimation* anim ) { if (!NightLight::search_duplicate<NLAnimation*>(anim)) m_animationList.push_back(anim); }