Problem mit deques



  • hi,
    Ich habe ein Problem mit Listen.
    Ich will meine Spriteobjekte in dem vector SPRITESTO(sprites in der initgame-funkion) speichern, aber nur die Adressen der enthaltenen Objekte zum aufruf verwenden, damit ich sie von unterschiedlichen Stellen in meinen Szenengraphen aufrufen kann, ohne kopieen zu benötigen.
    Ich erzeuge mir also ein temporäres Spriteobjekt und schiebe es in meinen spritesto-vector.
    Von dieser kopie hole ich mir nun die Adresse und speichere sie in der viewlist-deque (später im playfieldnode ,aber das ist derzeit deaktiviert).

    an anderer Stelle will ich über die viewlist auf die sprites zugreifen um sie zu rendern.
    ABER ich bekomme immer eine acces violation 😞 warum 😕
    hänge an diesem Problem schon eine ganze Woche und
    wäre für jegliche Hilfe dankbar
    tschao
    lukas

    ach ja der code (zumindest das wichtigste, ansonst währe es zuviel)

    //in main.cpp:
    deque<ani_c> tex;	
    deque<spritenode_c*> viewlist; 
    cameranode_c camera;
    playfieldnode_c playfieldnode;
    vector<spritenode_c> spritessto;//here the spritenodes will be saved
    playfieldnode_c playfieldnode;
    char path[]="C:/Daten/Gramming/CPP/MyProjects/sourcefiles/pics/";
    //....und andere 
    initGame(path,&tex,&playfieldnode,&camera,&spritessto,&viewlist);
    RefreshScreen(SDLscreen,&playfieldnode,&camera,&viewlist);
    
    //in deffinitions.cpp
    bool initGame(char*path,deque<ani_c> *tex,
    					 playfieldnode_c *playfieldnode,
    					 cameranode_c *camera,
    					 vector<spritenode_c>* sprites,
    					 deque<spritenode_c*> *viewlist)
    {
        spritenode_c initspriteobject;
        int nx=5,ny=5;
        for(int ii=0;ii<nx;ii++)
        { 
        	for(int i=0;i<ny;i++)
    	{	
    		spritenode_c *initsprite;
    
    		sprites->push_back(initspriteobject);//save object
                        //get pointer to object
    		initsprite=&sprites->at(sprites->size()-1);
    
    		viewlist->push_back(initsprite);//save pointer to pointerlist
    
    		initsprite->setPos(128+i*64*1,128+ii*64*2);
    		initsprite->setSize(64,64);
                        //... und eine langeliste ahnlicher initialisierungen
    
    	}
        }
        //... und weitere (derzeit deaktivierte) initialisierungen
    }
    
    void RefreshScreen(SDL_Surface *SDLscreen,
    					 playfieldnode_c *playfield,
    					 cameranode_c *camera,
    					 deque<spritenode_c*> *viewlist)
    {	
    
             //diverse gl-befehle
    
    	glLoadIdentity();
    
    	for(int i=0;i<viewlist->size();i++)
    	{
    		viewlist->at(i)->drawIt(false,0,0,0,0,1);
    		printf("i:%i\n",i);
    		printf("allo:%i\n\n",viewlist->at(i)->allo);
    	}
    
    	glFlush();						
    }
    


  • hab deinen Code nur überflogen, aber vielleicht ist das der Fehler:

    initsprite=&sprites->at(sprites->size()-1); 
    
    viewlist->push_back(initsprite);//save pointer to pointerlist
    

    Du holst dir die Adresse des letzten Elements und speicherst sie in viewlist. Das ist allerdings die Adresse einer lokalen Variablen, die es nach der Funktion nicht mehr gibt. Beim Rendern kriegst du dann ne access. vio.



  • Ich weiß zwar nicht ob du die Adresse des letzten Elementes der sprites oder die Adresse von viewlist meinst, aber ich habe die viewlist und auch die sprites by reference übergeben. Sie dürften also eigentlich nicht lokal sein.
    habe es mit klammersetzung probiert:
    initsprite=&(sprites->at(sprites->size()-1));
    hilft leider auch nicht, leider 😞
    by



  • Du hast mich nicht verstanden. Du übergibst in dem ganzen Sourcecode nirgends by reference. Wenn du einen Zeiger übergibst, dann wird der Zeiger selbst per value übergeben.
    Nochmal:
    Du hast in initGame eine lokale Variable namens initspriteobject. Deren Adresse fügst du in viewlist ein. Nach verlassen der Funktion zeigen deine Zeiger auf einen ungültigen Bereich.



  • interpreter schrieb:

    Du hast mich nicht verstanden. Du übergibst in dem ganzen Sourcecode nirgends by reference. Wenn du einen Zeiger übergibst, dann wird der Zeiger selbst per value übergeben.

    Und? Er übergibt die Adresse im vector gespeicherten Objekts und nicht die Adresse der localen Variable...



  • Nochmal:
    Du hast in initGame eine lokale Variable namens initspriteobject. Deren Adresse fügst du in viewlist ein. Nach verlassen der Funktion zeigen deine Zeiger auf einen ungültigen Bereich.

    Nee,
    ich fertige doch mit initspriteobject nur eine Kopie an

    sprites->push_back(initspriteobject);//save object
    

    die Elemente von sprites sind keine Zeiger auf Sprites sondern sind
    sprite_c-Objekte
    erst von dieser Kopie die nicht lokal sein dürfte, hole ich mir die Adresse

    initsprite=&sprites->at(sprites->size()-1);
    

    und speichere sie in meiner viewlist

    viewlist->push_back(initsprite);//save pointer to pointerlist
    


  • Wenn du in einen vector push_backst, werden Zeiger und Iteratoren auf enthaltene Elemente ungültig. Du könntest z.B. nur die Indizes der Elemente in der deque speichern. Oder wenn das nicht geht, eine list nehmen (die hat lockerere Invalidierungsregeln) oder die Elemente per new allokieren und sowohl im vector als auch in der deque Zeiger speichern.



  • Ein vector wächst je nach Bedarf, um zu wachsen benötigt der vector neuen Speicher, das heißt, die vorhandenen Objekte werden zerstört und neuer Speicher wird alloziert. Alle Zeiger die du vorher gepspeichert hast werden ungültig. Deshalb falls du nicht gerade auf Random Iterators bzw. auf die at-Methode angewiesen bist, würde ich in diesem Fall eine list nehmen. Oder du lässt deinen vector vorher etwas mehr Speicher mittels reserve reservieren.



  • In der vorhergehenden Version meines Programmes hat die sprite_c ihrerseits
    eine deque von sprite_c Elementen enthalten.(bildet einen Szenengraphenbaum)
    Das hat zwar wunderbar funktioniert, aber ich konnte nicht gleiche Endstücke an verschiedene Stellen hängen.(und andere spielereien die hier nicht näher interessieren)
    auf jeden fall will ich jetzt zeigerlisten als baumverbindungen benutzen
    wie mache ich das dann am besten?

    ach ja der vector währe zum speichern gedacht gewesen, also einfach eine ungeordnete Ansammlung aller benötigten Sprite-Objekten

    die deques währen zur dynamischen verwaltung der spriteobjekte über zeiger gedacht gewesen

    das geht also mit list besser? (keine indizesverschiebung?)
    mit deques ist es also reines russisches roulett. aha 🙄
    ich were es mal versuchen
    danke


Anmelden zum Antworten