Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 07.01.2008, 22:45 Titel: |
|
|
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 |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 08.01.2008, 12:57 Titel: |
|
|
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 |
|
|
LeeDiGer Super JLI'ler
Anmeldedatum: 31.08.2003 Beiträge: 366 Wohnort: Duisburg Medaillen: Keine
|
Verfasst am: 11.01.2008, 01:15 Titel: |
|
|
Öhmmm...also ich hab jetzt folgendes probiert:
ich habe anstatt
mal das hier eingesetzt:
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 |
|
|
Deviloper Junior JLI'ler
Anmeldedatum: 31.05.2006 Beiträge: 77
Medaillen: Keine
|
Verfasst am: 11.01.2008, 09:25 Titel: |
|
|
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 |
|
|
LeeDiGer Super JLI'ler
Anmeldedatum: 31.08.2003 Beiträge: 366 Wohnort: Duisburg Medaillen: Keine
|
Verfasst am: 11.01.2008, 13:37 Titel: |
|
|
Oh mann. Ich hab wieder etwas neues zu berichten
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 |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 11.01.2008, 15:10 Titel: |
|
|
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 |
|
|
LeeDiGer Super JLI'ler
Anmeldedatum: 31.08.2003 Beiträge: 366 Wohnort: Duisburg Medaillen: Keine
|
Verfasst am: 12.01.2008, 04:32 Titel: |
|
|
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
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 ), 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 _________________ Kein Rückzug! Kein Aufgeben! |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 12.01.2008, 16:18 Titel: |
|
|
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
Gruß DXer |
|
Nach oben |
|
|
LeeDiGer Super JLI'ler
Anmeldedatum: 31.08.2003 Beiträge: 366 Wohnort: Duisburg Medaillen: Keine
|
Verfasst am: 23.01.2008, 22:43 Titel: |
|
|
Ich hab wieder ein neues Problem
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 ) 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 |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 24.01.2008, 01:19 Titel: |
|
|
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 |
|
|
Deviloper Junior JLI'ler
Anmeldedatum: 31.05.2006 Beiträge: 77
Medaillen: Keine
|
Verfasst am: 24.01.2008, 16:20 Titel: |
|
|
Und auf new [] das ensprechende delete []
Ehm warum gibst du den Speicher nicht einfach im Destruktor deiner Struktur frei? Insgesamt scheinst du nen komisches Klassendesign zu haben |
|
Nach oben |
|
|
LeeDiGer Super JLI'ler
Anmeldedatum: 31.08.2003 Beiträge: 366 Wohnort: Duisburg Medaillen: Keine
|
Verfasst am: 24.01.2008, 17:46 Titel: |
|
|
"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
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 |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 24.01.2008, 17:54 Titel: |
|
|
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 |
|
|
LeeDiGer Super JLI'ler
Anmeldedatum: 31.08.2003 Beiträge: 366 Wohnort: Duisburg Medaillen: Keine
|
Verfasst am: 24.01.2008, 18:37 Titel: |
|
|
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
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 _________________ Kein Rückzug! Kein Aufgeben! |
|
Nach oben |
|
|
Deviloper Junior JLI'ler
Anmeldedatum: 31.05.2006 Beiträge: 77
Medaillen: Keine
|
Verfasst am: 24.01.2008, 18:43 Titel: |
|
|
Hmm zeig mal dein ganzes Projekt. Da ist irgendwie überall ein wenig rumgepfuscht!
Und das Klassendesign ... wo ist es?
(aja guck mal wo der unterschied zwischen ++x und x++ liegt ) |
|
Nach oben |
|
|
|