JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=423e7b34fe642a97a9d2e402f9289b50Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Problem mit STL list

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
MichaelB
Mini JLI'ler



Anmeldedatum: 09.07.2005
Beiträge: 27

Medaillen: Keine

BeitragVerfasst am: 08.08.2005, 13:14    Titel: Problem mit STL list Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
HotAcid
Super JLI'ler


Alter: 43
Anmeldedatum: 04.08.2002
Beiträge: 372
Wohnort: Berlin
Medaillen: Keine

BeitragVerfasst am: 08.08.2005, 15:44    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
MichaelB
Mini JLI'ler



Anmeldedatum: 09.07.2005
Beiträge: 27

Medaillen: Keine

BeitragVerfasst am: 08.08.2005, 16:32    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Sören
JLI Master Trainee



Anmeldedatum: 26.07.2002
Beiträge: 647
Wohnort: Bonn
Medaillen: Keine

BeitragVerfasst am: 08.08.2005, 21:50    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 08.08.2005, 23:00    Titel: Antworten mit Zitat

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 Wink
</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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Leviathan
Mini JLI'ler


Alter: 49
Anmeldedatum: 12.01.2005
Beiträge: 31
Wohnort: S9
Medaillen: Keine

BeitragVerfasst am: 09.08.2005, 09:19    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Leviathan
Mini JLI'ler


Alter: 49
Anmeldedatum: 12.01.2005
Beiträge: 31
Wohnort: S9
Medaillen: Keine

BeitragVerfasst am: 09.08.2005, 09:58    Titel: Antworten mit Zitat

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
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
Seite 1 von 1

 
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