Hi really need help - Pointer checks

Started by
18 comments, last by rozz666 16 years, 9 months ago
Striken, there's a lot more compact version that does the same. The std::vector::erase() function will erase a given object from a vector, but you still have to find at which position it's stored, since it accepts either an iterator, or a start and end iterator.

The std::remove() function takes a begin and end iterator, and the object you want to remove. What this function does, when it finds the given item, is moving all next elements in the vector to the left, which overwrites the found item, but leaves one extra item at the end of the list. Once it's finished, it returns an iterator to the end of the list, minus the number of items removed.

Combining the two allows you to remove all found items, and then erase the leftover items at the end of the list, by calling std::vector::erase() with the iterator that std::remove() returned, and std::vector::end() as the end iterator. In the end, this saves you from writing search code, as std::remove() will find all occurences of the item you want to remove.

// Clear up the object that itemToBeRemoved pointed to:delete itemToBeRemoved;// Now erase that pointer from our vector of sprite pointers:spriteContainer.erase(   std::remove(   spriteContainer.begin(), spriteContainer.end(), itemToBeRemoved   ), spriteContainer.end()   );
Create-ivity - a game development blog Mouseover for more information.
Advertisement
oh that's sweet :) thanks, i've always thought the way I did it was a bit of a mouthful! I presume that implementation is faster? as i'm using mutexes with this search embedded during locks (for my networking code) that little snippet will be most useful!
- Teach a programmer an answer, he can code for a day. Show a programmer the documentation, he can code for a lifetime.
thanks guys i will take the various approach suggested :)
Hi i have another problem say for example i make an entityManager which handles the sprite and rendering etc i have a removeEntity method which deletes the entity sprite vector and calls the remove sprite method from the renderManager aswell but the engine crashes?

here is some code for the entityManager

////ENTITY MANAGER HEADER#ifndef ENTITYMANAGER_H#define ENTITYMANAGER_H#include "Globals.h"class Sprite;class RenderManager;class EntityManager{public:	EntityManager();	~EntityManager();	void AddEntity(Sprite *const entityToAdd);	void RemoveEntity(Sprite *const entityToRemove);	const size_t EntitySize() {return m_EntityList.size();}	Sprite *GetEntity(Sprite *const entityToFind);	void Update();	void Render();private:	RenderManager *RM;	protected:	vector<Sprite *> m_EntityList;};extern EntityManager *pEM;#endif///ENTITY MANAGER CPP#include "EntityManager.h"#include "Sprite.h"#include "RenderManager.h"EntityManager *pEM = NULL;EntityManager::EntityManager(){	pEM=this;	RM = new RenderManager();}EntityManager::~EntityManager(){	if(!m_EntityList.empty()){		vector<Sprite *>::iterator iEntity;		for(iEntity = m_EntityList.begin(); iEntity != m_EntityList.end(); iEntity++){			if((*iEntity)){				delete (*iEntity); 				(*iEntity)=NULL;			}		}	}	if(RM){delete RM; RM=NULL;}}void EntityManager::AddEntity(Sprite *const entityToAdd){	if(entityToAdd != NULL){		m_EntityList.push_back(entityToAdd);		if(RM)RM->AddSprite(entityToAdd);	}}void EntityManager::RemoveEntity(Sprite *const entityToRemove){	if(entityToRemove)	{		if(!m_EntityList.empty()){			vector<Sprite *>::iterator iEntity;			for(iEntity = m_EntityList.begin(); iEntity != m_EntityList.end(); iEntity++){				if((*iEntity) == entityToRemove){					delete (*iEntity); 					(*iEntity)=NULL;					break;				}			}		}		if(RM)RM->Remove(entityToRemove);	}}Sprite *EntityManager::GetEntity(Sprite *const entityToFind){	vector<Sprite *>::iterator iEntity;	if(entityToFind)	{		if(!m_EntityList.empty()){			for(iEntity = m_EntityList.begin(); iEntity != m_EntityList.end(); iEntity++){				if((*iEntity) == entityToFind){					return (*iEntity); 					break;				}			}		}	}	return (*iEntity);}void EntityManager::Update(){}void EntityManager::Render(){	if(RM)RM->Render();}



Ok somewhere in main i got this

EM = new EntityManager();
EM->AddEntity(ken = new Ken());

EM->Render();

if(dxuKeyState[DIK_B]){
EM->RemoveEntity(ken); //crashes here
}

the EntityManager initiates an instance of RenderManager and calls the RenderMethod

what i was trying to do is basically have the sprite deleted from all the managers if removed from the entity manager but it seems i have the same problem from before it now complains about RenderManager remove method???

> Fusion.exe!RenderManager::Remove(Sprite * const pSprite=0x003994c0) Line 48 + 0x23 bytes C++
Does RenderManager::Remove() also deletes the sprite? If it does, there's your problem - the entity manager already deleted it and you can't call delete an object more than once.
Your problem is here:

if(!m_EntityList.empty()){
vector<Sprite *>::iterator iEntity;
for(iEntity = m_EntityList.begin(); iEntity != m_EntityList.end(); iEntity++){
if((*iEntity) == entityToRemove){
delete (*iEntity); <----- hehe
(*iEntity)=NULL;
break;
}
}
}

You are deleting the same pointer more than once.
You should do something like this:

m_EntityList.remove(entityToRemove);
RM->remove(entityToRemove);
delete entityToRemove;

BTW why do you use things like Sprite *const entityToRemove?
Do you need constant pointers?
Hi thanx agains guys i think i have sorted it out, one more thing though :)

How would i create a copy of a sprite without pointing to it, what i want is basically to copy all of (sprite A) to (sprite B) but with its own memory, so B doesn't affect A or vice versa, what do i need to do in the SpriteClass in order to achieve this?
There are lots of optiopns. You can implement a copy constructor SpriteClass(const SpriteClass& ), write a copy() or clone() function, or implement operator=(SpriteClass& ). I would suggest the first and second options since I presume you don't want to copy one sprite data to an existing sprite.
So basically you write a constructor that copies data from a given sprite (remember to write m_ThisFrame = new FRAME(); etc. instead of copying the pointers). Then write the copy function:

SpriteClass *SpriteClass:copy()
{
return new SpriteClass(*this);
}

the constructor should be smoething like this:

SpriteClass::SpriteClass(const SpriteClass& sc)
{
m_ThisFrame = new FRAME();
m_CurrentAttack = new ATTACK();
m_CurrentAttack->bBox = new BOUNDING_BOX();

m_ThisFrame->SPRITE_ID = sc.m_ThisFrame->SPRITE_ID;
m_ThisFrame->VALID_ID = sc.m_ThisFrame->VALID_ID;

// etc. or you can implement FRAME::operator= and write
// *m_ThisFrame = *sc.m_ThisFrame
}
Hmm also how would i instance the vectors that hold the sprite data when cloning?

i.e i have some vectors in the SpriteClass pointing to something, how do copy these?

vector<SPRITE *> m_Sprite how would i copy something like this in the constructor?

[Edited by - lodoss118 on July 14, 2007 5:21:21 PM]
std::vector<> has it's operator= implemented. So there's no problem copying the vector. What you should consider is if you want to just copy the pointers in the vector or copy them too (which means using new with copy constructors).

This topic is closed to new replies.

Advertisement