|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
MichaelB Mini JLI'ler
Anmeldedatum: 09.07.2005 Beiträge: 27
Medaillen: Keine
|
Verfasst am: 08.08.2005, 13:14 Titel: Problem mit STL list |
|
|
Hallo,
habe ein Problem mit list aus der STL: Ich habe eine Klasse, die eine list als privaten Member hat.
Eine Instanz dieser Klasse funktioniert absolut einwandfrei.
Sobald es zwei werden, renne ich in Zugriffsverletzungen, sobald auf Funktionen der list zugegriffen werden soll, z.B. empty() - dann zeigt der Debugger die Variable _MyHead innerhalb der STL Implementierung als undefiniert an, fast so als wäre kein Platz mehr zum Anlegen der zweiten list vorhanden...?
0xC0000005: Zugriffsverletzung-Leseposition 0x00000012.
- this 0x0000000a {size=???} const std::list<CSprite *,std::allocator<CSprite *> > * const
- _Myhead CXX0017: Fehler: Symbol "" nicht gefunden std::_List_nod<CSprite *,std::allocator<CSprite *> >::_Node *
Aufruf der Klasse aus der Main.cpp :
Code: | CShotsList* ShotList = new CShotsList(p_D3D->GetD3Device(),pTexture);
CShotsList* ShotList2 = new CShotsList(p_D3D->GetD3Device(),pTexture);
ShotList->Draw(Framerate); // funktioniert
ShotList2->Draw(Framerate); // wirft Zugriffsverletzung |
Die Klasse:
Code: | #pragma once
#include <list>
#include "Sprite.h"
#include "Main.h"
class CShotsList
{
public:
CShotsList(LPDIRECT3DDEVICE9 lpDevice, LPDIRECT3DTEXTURE9 lpTexture);
~CShotsList(void);
void AddShot(D3DXVECTOR2 vPosition);
void Draw(int Framerate);
private:
LPDIRECT3DTEXTURE9 m_lpShotTexture;
// Zeiger auf das Direct3D Device
LPDIRECT3DDEVICE9 m_lpDevice;
std::list<CSprite*>ShotList;
std::list<CSprite*>::iterator m_it, m_it2;
};
|
Code: | #include ".\shotslist.h"
CShotsList::CShotsList(LPDIRECT3DDEVICE9 lpDevice, LPDIRECT3DTEXTURE9 lpTexture)
{
m_lpShotTexture = lpTexture;
m_lpDevice = lpDevice;
}
CShotsList::~CShotsList(void)
{
ShotList.clear();
}
void CShotsList::AddShot(D3DXVECTOR2 vPosition)
{
CSprite* ShotSprite = new CSprite(m_lpDevice, m_lpShotTexture);
ShotSprite->SetStep(SHOT_SPEED,0.0f);
ShotSprite->SetPosition(vPosition.x,vPosition.y);
ShotList.push_front(ShotSprite);
}
void CShotsList::Draw(int Framerate)
{
if (ShotList.empty())
return;
m_it = ShotList.begin();
while (m_it != ShotList.end())
{
CSprite* pSprite = *m_it; // Hole Element
pSprite->Draw();
pSprite->Move(RIGHT,Framerate);
if (pSprite->GetPosition().x > SCR_WIDTH)
{
m_it2 = m_it;
m_it2++;
ShotList.erase(m_it);
m_it = m_it2;
}
else
m_it++; // erhöhe Iterator
}
} |
Danke im vorab,
Michael
Zuletzt bearbeitet von MichaelB am 08.08.2005, 17:04, insgesamt 2-mal bearbeitet |
|
Nach oben |
|
|
HotAcid Super JLI'ler
Alter: 43 Anmeldedatum: 04.08.2002 Beiträge: 372 Wohnort: Berlin Medaillen: Keine
|
Verfasst am: 08.08.2005, 15:44 Titel: |
|
|
habe ich das jetzt so richtig verstanden:
eine Instanz dieser Liste funktioniert. Wenn du zwei Instanzen hast, funktioniert es nicht mehr, richtig?
das Problem kann ich jetzt nicht finden, aber du erzeugst auf jeden Fall damit ein Speicherleck in der Größe der Sahara, du erzeugst zwar permanent neue Sprites, aber ich sehe in dem Code kein einziges delete.
Deine Variante, einen Schuss zu löschen, finde ich auch etwas "abenteuerlich", es gibt doch extra Funktionen für das Löschen eines Elementes aus einer Liste, guckst du hier: STL-List
bye
Felix _________________ StGB §§ 328 Abs. 2 Pkt 3:
Mit Freiheitsstrafe bis zu fünf Jahren oder mit Geldstrafe wird bestraft, wer eine nukleare Explosion verursacht. |
|
Nach oben |
|
|
MichaelB Mini JLI'ler
Anmeldedatum: 09.07.2005 Beiträge: 27
Medaillen: Keine
|
Verfasst am: 08.08.2005, 16:32 Titel: |
|
|
Erstmal danke für die Antwort.
HotAcid hat Folgendes geschrieben: | eine Instanz dieser Liste funktioniert. Wenn du zwei Instanzen hast, funktioniert es nicht mehr, richtig? |
Yup. Und zwar schon, bevor überhaupt ein einziges Element per 'AddShot' eingefügt wurde.
Zitat: | du erzeugst auf jeden Fall damit ein Speicherleck in der Größe der Sahara, du erzeugst zwar permanent neue Sprites, aber ich sehe in dem Code kein einziges delete. |
Erase erfüllt nicht die gewünschte Funktion, ein Element aus der Liste zu löschen? An welcher Stelle entsteht das Speicherleck?
Zitat: | Deine Variante, einen Schuss zu löschen, finde ich auch etwas "abenteuerlich", es gibt doch extra Funktionen für das Löschen eines Elementes aus einer Liste |
Ok, eleganter wäre wohl:
Code: | while (m_it != ShotList.end())
{
pSprite = *m_it; // Hole Element
pSprite->Draw();
pSprite->Move(RIGHT,Framerate);
if (pSprite->GetX() > SCR_WIDTH)
m_it = ShotList.erase(m_it);
else
m_it++;
} |
Hm, wenn ich dem Link folge, steht da:
"iterator erase(iterator pos) Sequence Erases the element at position pos."
Ein 'delete' gibt es in std::list nicht...
bye
Felix |
|
Nach oben |
|
|
Sören JLI Master Trainee
Anmeldedatum: 26.07.2002 Beiträge: 647 Wohnort: Bonn Medaillen: Keine
|
Verfasst am: 08.08.2005, 21:50 Titel: |
|
|
Wenn du Speicher mit new anforderst solltest du diesen auch mit delete wieder freigeben. Mit list.erase reinigst du nur die liste. Da sich in der Liste aber nur Zeiger auf die eigentlichen Objekte befinden, löscht du so nur die Zeiger nicht aber die Objekte selber. Deshalb solltest du in einer for schleife alle objekte durch gehen, delete aufrufen und auf null setzen. |
|
Nach oben |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 08.08.2005, 23:00 Titel: |
|
|
Wieso verwendest du in diesem Fall überhaupt new&delete?
Wenn du eine STL-List verwendest, brauchst du dich nicht mehr um die Freigabe des Speichers kümmern. Das übernimmt wie du richtig gesagt hast erase(), clear(), der Destruktor u.a.
Du musst dich aber sehr wohl darum kümmern, wenn du die Zeigerelemente davor per new erstellst.
Aber viel einfacher wäre es, wenn du dein CSprite ganz normal erstellst(kein Zeiger, kein new) und der Liste hinzufügst:
CPP: | CSprite ShotSprite = CSprite(m_lpDevice, m_lpShotTexture);
ShotSprite.SetStep(SHOT_SPEED,0.0f);
ShotSprite.SetPosition(vPosition.x,vPosition.y);
ShotList.push_front(ShotSprite); |
Für den Listentyp dann natürlich das:
CPP: | std::list<CSprite>ShotList; |
<edit>
new und delete wird in den meisten Fällen eingesetzt, wenn man dynamischen Speicher haben will. Mit der STL-List hast du den ja schon, brauchst also new nicht mehr
</edit> _________________ 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 |
|
|
Leviathan Mini JLI'ler
Alter: 49 Anmeldedatum: 12.01.2005 Beiträge: 31 Wohnort: S9 Medaillen: Keine
|
Verfasst am: 09.08.2005, 09:19 Titel: |
|
|
The Lord of Programming hat Folgendes geschrieben: |
Aber viel einfacher wäre es, wenn du dein CSprite ganz normal erstellst(kein Zeiger, kein new) und der Liste hinzufügst:
CPP: | CSprite ShotSprite = CSprite(m_lpDevice, m_lpShotTexture);
ShotSprite.SetStep(SHOT_SPEED,0.0f);
ShotSprite.SetPosition(vPosition.x,vPosition.y);
ShotList.push_front(ShotSprite); |
Für den Listentyp dann natürlich das:
CPP: | std::list<CSprite>ShotList; |
|
Hi!
Hi! Ich schlage mich auch wie der Ersteller des Threads mit dem Freigeben des Speichers rum, wenn bspw. der shot aus dem Bildschrim rausfliegt.
Bisher habe ich keine vernünftige Lösung gefunden... Christian in seinem Buch gibt sich damit zufrieden, die shots erst im Destruktor freizugeben, also wenn das Spiel beendet wird... ich glaube, dass das keine gute Lösung ist.
@ Lord of Programming
Ich habe Deine Lösung ausprobiert.
1. Es kompiliert nur dann wenn ich statt "ShotList.push_front(ShotSprite)" "ShotList.push_front(&ShotSprite)" implementiere
2. Wenn dann aber während des Spiels ein shot erzeugt wird, bekomme ich eine böse Exception..
Gruß |
|
Nach oben |
|
|
Leviathan Mini JLI'ler
Alter: 49 Anmeldedatum: 12.01.2005 Beiträge: 31 Wohnort: S9 Medaillen: Keine
|
Verfasst am: 09.08.2005, 09:58 Titel: |
|
|
ok... hab den Fehler bei mir gefunden... hatte die Liste nämlich so definiert:
Code: |
list<CSprite*> m_AsteroidList;
|
Somit brauche ich den Speicher für die shots u.ä. nicht mehr freigeben! Klasse!
Danke. |
|
Nach oben |
|
|
|
|
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
|