Skip to main content
gamedev.net
🔒 Locked

std::map.. , vector* is creating non NULL pointers ...?

Started by MTclip 2 replies 400+ views
Original Post
MTclip
MTclip
im not 100% sure that its creating non-NULL pointers but i dont know what else it could be doing.. THIS IS HOW I CHECK FOR NULL

	Agent * newAgent = NULL;
	for (std::map<std::string, std::vector<Agent*> >::iterator iterator = agentMap.begin(); iterator != agentMap.end(); ++iterator) 
	{
		for (std::vector<Agent*>::iterator agentIterator = iterator->second.begin(); agentIterator != iterator->second.end(); ++agentIterator) 
		{
                         // NULL CHECKING	                 
                         if((*agentIterator) == NULL)
				continue;
                         
                         // crashes inside v--this function call after addAdd.. because (*agentIterator) is undefined 
			(*agentIterator)->Perceive(agentMap);
			(*agentIterator)->Decide();
                        // returns new Agent or NULL
			newAgent = (*agentIterator)->Perform(m_timer.m_elapsedTime);
			(*agentIterator)->Update(m_timer.m_elapsedTime);
			terrain->PutInBounds((*agentIterator)->m_state.GetPos());

			if(newAgent != NULL)
				AddAgent(newAgent); // adds agent to the map
		}
	}


// AddAgent

void Test::AddAgent(Agent * pAgent)
{
	if(pAgent == NULL)
		return;

	char buf[12];
	agentID++;
	std::string ID = "Agent_";    
	ID += itoa(agentID,buf,10);
	(std::string)pAgent->GetName() = ID;

	agentMap[pAgent->m_pStats->m_agentType].push_back(pAgent);
}

///////// THE NEXT TO MAY NOT BE NEEDED BUT THEY COMPLETE THE CHAIN FROM NEW TO addAgent()...... /////////////// Agent::perform()

Agent * Agent::Perform(float eTime)
{
        // other code clipped
        if(m_action == "mate")
	{
		return Mate(m_pTarget);
	}
        return NULL;
}

Agent::Mate()

Agent * Agent::Mate(Agent *& rAgent)
{
	if(!rAgent->m_state.m_canAction)		
        return NULL;
	
	// create new
	Behavior * pBeh = new Behavior("Beh_offspring_");
	Stats * pStats = new Stats("Stat_offspring_");
	
	pStats->Merge(*m_pStats, *rAgent->m_pStats, MUTATION);
	pBeh->Merge(*m_pBehavior, *rAgent->m_pBehavior, MUTATION);

	WereModel * pModel = NULL;
	if((rand() % 2) == 0)
		pModel = m_pModel;
	else
		pModel = rAgent->m_pModel;
	
	// create new 
	Agent * pnew = new Agent(pBeh,pStats,pModel, "Agent_");

	// move to midpoint of parents
	pnew->MoveTo((m_state.m_pos.m_position.x + rAgent->m_state.m_pos.m_position.x) * 0.5f, 
				(m_state.m_pos.m_position.y + rAgent->m_state.m_pos.m_position.y) * 0.5f, 
				(m_state.m_pos.m_position.z + rAgent->m_state.m_pos.m_position.z) * 0.5f);

	return pnew;
}

ive followed the call from "Mate()"all the way to where it adds and the agent is fully defined... also I can call addAgent() all that i want durring my loading process, but durring run-time, it will crash... so the vector inside the map must be allocating non NULL Agent* any Ideas..
Conner McCloud
Conner McCloud
I am about to go to bed, so I haven't thoroughly reviewed your code. Apologies if a brief scan missed the part where you already know what I'm about to say.

Unless you are telling containers to add a NULL pointer, they isn't going to do so for you. Default constructors are called if you don't specify an actual value...in the case of pointers, this means junk addresses.

*edit: There's less code there than I thought...where do you actually call AddAgent? I don't see any references to it except one that is after the point that you say crashes.

*edit2: That call to addAgent might be a problem, actually. You're pushing an object onto your vector, but that can easily invalidate all iterators that reference that vector if the push_back requires a resize. If that happens, then agentIterator ends up invalid, but you still call ++agentIterator, which puts you into junk memory.

CM
MTclip
MTclip
yeah.. i think i have it working now ...more testing...
kept a list of the new Agents then added them after the iterator is done..

void Test::UpdateAgents(){	std::vector<Agent *> AgentVec;	Agent * newAgent = NULL;	for (std::map<std::string, std::vector<Agent*> >::iterator iterator = agentMap.begin(); iterator != agentMap.end(); ++iterator) 	{		for (std::vector<Agent*>::iterator agentIterator = iterator->second.begin(); agentIterator != iterator->second.end(); ++agentIterator) 		{	        if((agentIterator) == NULL)				continue;			(*agentIterator)->Perceive(agentMap);			(*agentIterator)->Decide();			newAgent = (*agentIterator)->Perform(m_timer.m_elapsedTime);			(*agentIterator)->Update(m_timer.m_elapsedTime);			terrain->PutInBounds((*agentIterator)->m_state.GetPos());			if(newAgent != NULL)				//LoadAgent("wolf_agent_01.txt");				AgentVec.push_back(newAgent);				//AddAgent(newAgent);		}	}	for(UINT i = 0; i < AgentVec.size(); i++)	{		AddAgent(AgentVec.at(i));	}}
iMalc
iMalc
Quote:
Original post by MTclip
yeah.. i think i have it working now ...more testing...
kept a list of the new Agents then added them after the iterator is done..

*** Source Snippet Removed ***
Yuck! I take it you don't mind long lines.
I thought you would have at least used a few typedefs as I showed in your other thread. I'm sure most people would find the example I gave much tidier.

So, you decided not to use a multi_map then?

Shouldn't your check for
                          if((*agentIterator) == NULL)
be an assert() instead of an if? I certainly recommend it. It's never something you want to happen, and an assert would notify you immediately if some bug ever allowed it to happen. Right now it'll work, but it could be silently ignoring a bug, now, or in the future.
The same goes for
	if(pAgent == NULL)
in AddAgent

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.