JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.phpMedaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Problem beim Löschen aus Vector
Gehe zu Seite Zurück  1, 2, 3  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Jonathan_Klein
Living Legend


Alter: 36
Anmeldedatum: 17.02.2003
Beiträge: 3431
Wohnort: Siegerland
Medaillen: Keine

BeitragVerfasst am: 07.01.2008, 23:45    Titel: Antworten mit Zitat

Aber bei erase wird der nächste Iterator zurückgegeben. Den benutzt du dann ja auch. Wenn du diesen am Ende dann nocheinmal erhöhst, haste logischerweise ein Objekt übersprungen.
Deshalb in der Schleife einfach testen ob das Objekt gelöscht werden soll, wenn ja den Iterator auf den Rückgabewert setzen und ansonsten den Iterator erhöhen.
_________________
https://jonathank.de/games/
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 08.01.2008, 13:57    Titel: Antworten mit Zitat

Jonathan_Klein hat Folgendes geschrieben:
DirectXer hat Folgendes geschrieben:
Jona: das bezieht sich auf eine list, bei vector ist das so nicht nötig.

Also meines Wissens nach, sind Iteratoren darauf ausgelegt, überall mit gleich zu funktionieren. Also sollte das so auch mit einem Vector funktionieren. Einen Versuch wär es auf jedenfall Wert.

Das stimmt, funktionieren tut es schon, da beides Forward-Iteratoren sind. Ein Vector-Iterator ist aber auch ein Random-Access-Iterator, d.h. dass man es damit leichter lösen kann. Du kannst z.B. mit vec[i] od. vec.at(i) auf ein beliebiges Objekt zugreifen und (was nocch wichtiger ist) mit vec.begin() + i auf ein beliebigen Iterator eines Objekts zugreifen.

@LeeDiGer: Jona hat Recht, du musst entweder den Iterator inkrementieren oder it = vec.erase(it) benutzen. Bei beiden zeigt er danach auf das nächste Element, nur bei erase() wird das vorherige gelöscht.
Ich hab den Snippet mal bei mir eingebaut(simuliert), und da funktioniert er. d.h. dass dein Fehler irgendwo anders im Code liegt und nicht hier.

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
LeeDiGer
Super JLI'ler



Anmeldedatum: 31.08.2003
Beiträge: 366
Wohnort: Duisburg
Medaillen: Keine

BeitragVerfasst am: 11.01.2008, 02:15    Titel: Antworten mit Zitat

Öhmmm...also ich hab jetzt folgendes probiert:
ich habe anstatt
CPP:
++itObjects2D;


mal das hier eingesetzt:
CPP:
itObjects2D++;


Den Rest den ich ganz am Anfang des Threads reingestellt hab, hab ich unverändert gelassen und jetzt wird alles restlos gelöscht.
Kennst jemand den Unterschied zwischen den 2 vorgezogenen Pluszeichen im gegensatz zu den 2 Pluszeichen dahinter?
_________________
Kein Rückzug! Kein Aufgeben!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Deviloper
Junior JLI'ler



Anmeldedatum: 31.05.2006
Beiträge: 77

Medaillen: Keine

BeitragVerfasst am: 11.01.2008, 10:25    Titel: Antworten mit Zitat

Sind zwei verschiedene Operatoren. Daran darf es aber normal nicht nutzen, da es nur bsw. eine Rolle (ja ich komm gleich noch zur Performance!) wenn du bsw. folgendes Konstrukt hast.
CPP:
foo var(0);
std::cout << var++ << std::endl;
std::cout << ++var << std::endl;
Solltest die Ausgabe
0
3
bekommen. Bei var++ wird erst das alte Zurück gegeben und dann Inkrementiert. Bei ++var wird einfach Inkrementiert und dann zurück gegeben.

So, darin liegt auch der Performanceunterschied. Für var++ wird eine Kopie des Orignals erstellt, dann das original Inkrementiert und dann die Kopie zurück gegeben.

Bei ++var wird einfach Inkrementiert und zurück gegeben (wahrscheinlich sogar auch beim Zurückgeben nur eine Referenz und keine Kopie).

Aber in deinem Fall sollte es also auch nur aus Performance-Sicht einen vorteil darstellen.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
LeeDiGer
Super JLI'ler



Anmeldedatum: 31.08.2003
Beiträge: 366
Wohnort: Duisburg
Medaillen: Keine

BeitragVerfasst am: 11.01.2008, 14:37    Titel: Antworten mit Zitat

Oh mann. Ich hab wieder etwas neues zu berichten Very HappyVery Happy
Das ganze hat solange funktioniert, solange mein programm so ausgelastet war, dass er stets unter 50 Frames hatte. Aber ich hab mal wieder einiges ausgebaut und wieder viel rumgeballert, bis mehrere 1000 Schüsse (Meshes) im Umlauf waren und da war wieder dieses Phänomen.

Aber irgendjemand hat hier angedeutet, dass der Fehler woanders liegen müsste.... ich hab jetzt folgendes zusätzlich eingebaut:

CPP:
   if(InputManager.Return){
      //Meshes auf Löschung überprüfen
      itObjects3D = itListObjects3D.begin();
      while(itObjects3D != itListObjects3D.end())
      {
         delete (*itObjects3D);
         itObjects3D = itListObjects3D.erase(itObjects3D);
      }
   }


Der Abschnitt löscht einfach alle Elemente blind, wenn man Return drückt. Die Funktion hat ja den Aufbau, so wie man es einem beigebracht hat....und spätestens dieser Codeschnipsel löscht gründlich.
Bleibt für mich die Frage, was mit den andern Meshes ist, die komischerweise nicht mehr zum rendern oder bewegen da sind, wenn ich in so einer schnellen abfolge welche erstellen lasse....
_________________
Kein Rückzug! Kein Aufgeben!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 11.01.2008, 16:10    Titel: Antworten mit Zitat

mal nur so ne frage: benutzt du mehrere Threads oder die Windows-Nachrichtenprozedur zum Löschen? Deine Aussage mit der FPS hat mich etwas stutzig gemacht...

Ich hab ja gesagt, dass der Fehler woanders liegen muss, zeig doch mal bitte etwas mehr code; am besten alle Refrenzen von listObjects2D

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
LeeDiGer
Super JLI'ler



Anmeldedatum: 31.08.2003
Beiträge: 366
Wohnort: Duisburg
Medaillen: Keine

BeitragVerfasst am: 12.01.2008, 05:32    Titel: Antworten mit Zitat

Ich benutze nur die Windowsschleife.
Hab jetzt mal als Löschbedingung mal ein Timeout eingebaut anstatt die maximale Entfernung zum Betrachter. Damit klappts problemlos.
Frag mich nicht warum Wink
Das mit dem Timeout sollte in der Praxis natürlich eher eingesetzt werden (eine Rakete soll ja einige sekunden fliegen dürfen, bis er ausgeht Wink), von daher wirds da keine Probleme mehr gehen.
Warum die Löschbedingung mit der Distanz zum Betrachter nicht einwandfrei geht, weiß ich auch nicht....aber damit braucht sich wohl erstmal niemand beschäftigen, weil sowas eh nie angewandt wird. hab ich nur mal zur vereinfachung mal getestet.
Jedenfalls ist wieder alles gut Wink
_________________
Kein Rückzug! Kein Aufgeben!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 12.01.2008, 17:18    Titel: Antworten mit Zitat

wenn du die Windowsschleife dafür benutzt, kann das daran liegen, da die u.U. mehrmals gleichzeitig aufgerufen werden kann. Aber ok, wenns jetzt klappt isses ja gut. Allerdings kann ich mir nicht erklären warums vorher net ging Rolling Eyes

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
LeeDiGer
Super JLI'ler



Anmeldedatum: 31.08.2003
Beiträge: 366
Wohnort: Duisburg
Medaillen: Keine

BeitragVerfasst am: 23.01.2008, 23:43    Titel: Antworten mit Zitat

Ich hab wieder ein neues Problem Wink

Gegeben ist folgende Struktur:

CPP:
//Grundstruktur der Waffen
struct m_SWeapon
{
   m_SSpaceship* Target;
   CBillboard* Billboard;
   int iType; //0:Schuss  1:Rakete
   ...
};


Dabei ist "Target" ein Zeiger auf ein 3DObjekt, in dem Fall ein Raumschiff, das die Rakete verfolgen soll. Die Raumschiffe werden ähnlich in einer Vectorliste gespeichert. Billboard ist der Zeiger auf die Billboardgrafik, die in einer anderen Liste angelegt wird für alle transparenten Objekte.
Beim Löschen der Rakete soll nur der Zeiger von Target wieder gelöscht werden (falls nötig Question Question ) und das komplette Billboard, welches die Grafik der Rakete repräsentiert, löschen (d.h. hinterher sollte tatsächlich das richtige Billboard aus der anderen liste ebenfalls gelöscht sein.)


Und ich möchte nach einem Timeout oder Kollision Raketen löschen:
CPP:
//Waffen auf Löschung überprüfen
itWeapon = listWeapon.begin();
while(itWeapon != listWeapon.end())
{
   ...
   case 1: //Raketen
      if((*itWeapon)->fTimeout <= 0)
      {
         delete ((*itWeapon))->Billboard;
         delete ((*itWeapon))->Target;
         delete (*itWeapon);
         itWeapon = listWeapon.erase(itWeapon);
         continue;
      }
   ...
}


So wie es hier steht, ist es wohl falsch. Es gibt hier Zugriffsfehler beim Versuch Billboard und Target (wenn ein Pointer selbst nicht freigegeben muss, dann lasst es mich wissen...bin mir jetzt irgendwie auch nicht mehr sicher) zu löschen. Wie müsste man das hier dann machen?
_________________
Kein Rückzug! Kein Aufgeben!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
The Lord of Programming
Living Legend


Alter: 36
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 24.01.2008, 02:19    Titel: Antworten mit Zitat

LeeDiGer hat Folgendes geschrieben:
So wie es hier steht, ist es wohl falsch. Es gibt hier Zugriffsfehler beim Versuch Billboard und Target (wenn ein Pointer selbst nicht freigegeben muss, dann lasst es mich wissen...bin mir jetzt irgendwie auch nicht mehr sicher) zu löschen. Wie müsste man das hier dann machen?

Pointer werden nicht freigegeben, sondern Speicher.

Ob der Speicher, auf den dein Pointer verweist, tatsächlich freigegeben werden muss oder dies vom Programm automatisch gemacht wird, hängt davon ab, wie du den Speicher belegst.
Belegst du den Speicher manuell mit dem Schlüsselwort "new" auf dem Heap, so musst du ihn auch wieder freigeben. Belegst du ihn auf dem Stack (Standard), wird das vom Programm übernommen.
Als Grundregel kannst du dir merken: Auf jedes new muss ein entsprechendes delete folgen.
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Deviloper
Junior JLI'ler



Anmeldedatum: 31.05.2006
Beiträge: 77

Medaillen: Keine

BeitragVerfasst am: 24.01.2008, 17:20    Titel: Antworten mit Zitat

Und auf new [] das ensprechende delete [] Wink

Ehm warum gibst du den Speicher nicht einfach im Destruktor deiner Struktur frei? Insgesamt scheinst du nen komisches Klassendesign zu haben Wink
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
LeeDiGer
Super JLI'ler



Anmeldedatum: 31.08.2003
Beiträge: 366
Wohnort: Duisburg
Medaillen: Keine

BeitragVerfasst am: 24.01.2008, 18:46    Titel: Antworten mit Zitat

"Billboard" ist zwar ne eigene Klasse mit Destruktor und der nötigen Speicherfreigabe, aber das da ist nicht das Problem.
Das Problem ist, dass ich für einen Schuss z.B. ein Element der Struktur "m_SWeapon" erstellt hab, welches als Member einen Pointer auf ein Element aus der "Billboard" Klasse enthält.

D.h. Schuss kommt in eine eigene Liste für Waffen. Und das Billboardelement kommt in einer andere Liste nur für Billboards aller arten (es können z.B. auch Billboards von reinen Partikeleffekten sein).

Also reicht es nicht, wenn ich einfach eine Cleanup Methode vom Billboard aufrufen, sondern es muss das komplette Element aus der Vectorliste der Billboards entfernt werden.

Zusammenfassend: Wie lösche ich ein Element aus der Billboardliste, wenn ich mich gerade die Liste der Waffen durchiteriere??

Zur Erinnerung: ich habe es nur mit STL-Vectoren anstatt STL-Listen zu tun Wink

CPP:
      vector<m_SWeapon*>::iterator itWeapon; //Iterator der Waffen
      vector<m_SWeapon*> listWeapon; //Liste der Waffen

      vector<CBillboard*>::iterator itBillboard; //Iterator der BillBoards
      vector<CBillboard*> listBillboard; //Liste der BillBoards

_________________
Kein Rückzug! Kein Aufgeben!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 24.01.2008, 18:54    Titel: Antworten mit Zitat

also heißt das dass du deine Objekte per new erzeugst? Dann ist das ok. Was Deviloper meint, ist folgendes:
CPP:
struct m_SWeapon
{
   // Destructor
   ~m_SWeapon()
   {
       delete Target;
       delete Billboard;
   }

   m_SSpaceship* Target;
   CBillboard* Billboard;
   int iType; //0:Schuss  1:Rakete
   ...
};

Hierbei musst du nur delete m_SWeapon und vector::erase aufrufen, die 2 internen deletes kommen automatisch.

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
LeeDiGer
Super JLI'ler



Anmeldedatum: 31.08.2003
Beiträge: 366
Wohnort: Duisburg
Medaillen: Keine

BeitragVerfasst am: 24.01.2008, 19:37    Titel: Antworten mit Zitat

Also meinen Analysen zufolge wird tatsächlich etwas gelöscht mit deiner Methode....nur verkleinert sich nicht die Vectorliste. Hab die Größe wieder mit size() abgefragt. Außerdem gibt es beim nächsten Renderdurchlauf einen Zugriffsfehler. Wie es scheint, bleibt nach diesem Löschvorgang noch ein ungültiges Element in der Billboardliste übrig....doch wie krieg ich den dann weg?
Ich hab hier bei meinen ganzen Versuchen nur Zeigerproblemorgien Sad

CPP:
//Anweisungsblock der Billboardobjekte und Rendern
for(itBillboard=listBillboard.begin();itBillboard!=listBillboard.end(); itBillboard++)
{
   //Billboards rendern
   (*itBillboard)->Render(Environment.m_Position+Environment.m_Zoom,Environment.m_LookAt);
   ...
}

Hier krachts nochmal Wink
_________________
Kein Rückzug! Kein Aufgeben!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Deviloper
Junior JLI'ler



Anmeldedatum: 31.05.2006
Beiträge: 77

Medaillen: Keine

BeitragVerfasst am: 24.01.2008, 19:43    Titel: Antworten mit Zitat

Hmm zeig mal dein ganzes Projekt. Da ist irgendwie überall ein wenig rumgepfuscht!

Und das Klassendesign ... wo ist es? Very Happy

(aja guck mal wo der unterschied zwischen ++x und x++ liegt Wink )
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung Alle Zeiten sind GMT
Gehe zu Seite Zurück  1, 2, 3  Weiter
Seite 2 von 3

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum