Sign in to follow this  
ankhd

STL List Interator, Whats Happens When You DO This obj *ptr = (obj*)&inter

Recommended Posts

ankhd    2304

Hi all.

 

I take it the above is bad. I get this expression("this->_Has_Container()",0);

 

if I do inter++;

 

and get this. Run-Time Check Failure #2 - Stack around  the variable 'meshcolour' was corrupted.

 

when I do ++inter;

 

 

 

 

Am I casting the list to my object and getting junk data.

 

How can I get my poiter the compiler complains when I do any of theses

pod = (cDropPodSate*)iter; error C2440: 'type cast' : cannot convert from 'std::list<_Ty>::_Iterator<_Secure_validation>' to 'cDropPodSate *'

pod = *iter; error C2440: '=' : cannot convert from 'cDropPodSate' to 'cDropPodSate *'

then comes
pod = (cDropPodSate*)&iter; compiles but crashes the app

 

But I do this now
done = iter->ProcessDropPod(timedelta);//works

 

 

here is the code

 

the object

//------------------------------------------------------------------------------------------------------
//this holds values for a instance of a droppod
//controls the motion and animation time for 1 droppod
//we dont have the mesh in this class we keep our animation time so we can play
//our current state
//-----------------------------------------------------------------------------------------------------
class cDropPodSate
{
private:
	D3DXVECTOR3 DropPodPosition;//we start in space and full to the ground and open the pod when we get 500 feet from the terrain
	D3DXVECTOR3 DropPodHeading;//the direction to target normalized this is where we land
	D3DXVECTOR3 DropPodVelocity;
	D3DXVECTOR3 DropPodTarget;//where on the terrain we clicked
	D3DXVECTOR3 DropPodDecelerate;//when we open the pod we start decelerating
	D3DXVECTOR3	DropPodScale;

	bool ActiveDropPod;//if a pod is in trancit we can deploy more

	bool OpenPod;//when we get to the height to open the pod we set this to true

	bool DropPodOnGround;//when where on the ground we wait a bit


	//we need a start time for the animation
	DWORD DropPodStartTime;//for when we open the pod
	DWORD DropPodGroundStartTime;//when we are on the ground we wait a bit
	DWORD DropPodElapsedTime;//precalculated for the render

public:
	cDropPodSate(void)
	{
		ActiveDropPod		= false;
		OpenPod			= false;
		DropPodOnGround		= false;
		DropPodStartTime		= 0;
		DropPodGroundStartTime	= 0;
		DropPodPosition		= D3DXVECTOR3();
		DropPodHeading		= D3DXVECTOR3();
		DropPodVelocity		= D3DXVECTOR3();
		DropPodTarget		= D3DXVECTOR3();
		DropPodDecelerate		= D3DXVECTOR3();
		DropPodScale		= D3DXVECTOR3(1.0, 1.0, 1.0);
		DropPodElapsedTime		= 0;


	}//end
	//////////////////////////////////////////////////////////////////


	//-----------------------------------------------------------
	//this will activate a pod
	//-----------------------------------------------------------
	cDropPodSate(D3DXVECTOR3 &start, D3DXVECTOR3 &target, D3DXVECTOR3 &scale)
	{
		ActiveDropPod		= false;
		OpenPod			= false;
		DropPodOnGround		= false;
		DropPodStartTime		= 0;
		DropPodGroundStartTime	= 0;
		DropPodPosition		= D3DXVECTOR3();
		DropPodHeading		= D3DXVECTOR3();
		DropPodVelocity		= D3DXVECTOR3();
		DropPodTarget		= D3DXVECTOR3();
		DropPodDecelerate		= D3DXVECTOR3();
		DropPodScale		= D3DXVECTOR3(1.0, 1.0, 1.0);
		DropPodElapsedTime		= 0;

		ActivateDropPod(start, target, scale);
	}//
	/////////////////////////////////////////////////////////////////////////

	const cDropPodSate& cDropPodSate::operator=(const cDropPodSate& s)
	{
		ActiveDropPod		= s.ActiveDropPod;
		OpenPod			= s.OpenPod;
		DropPodOnGround		= s.DropPodOnGround;
		DropPodStartTime		= s.DropPodStartTime;
		DropPodGroundStartTime	= s.DropPodGroundStartTime;
		DropPodPosition		= s.DropPodPosition;
		DropPodHeading		= s.DropPodHeading;
		DropPodVelocity		= s.DropPodVelocity;
		DropPodTarget		= s.DropPodTarget;
		DropPodDecelerate		= s.DropPodDecelerate;
		DropPodScale		= s.DropPodScale;
		DropPodElapsedTime		= s.DropPodElapsedTime;
		return *this;
	}



	~cDropPodSate(void)
	{
	}//
	/////////////////////////////////////////////////////////////////////////



	//---------------------------------------------------------------------
	//call this to activate the drop pod
	//---------------------------------------------------------------------
	void ActivateDropPod(D3DXVECTOR3 &start, D3DXVECTOR3 &target, D3DXVECTOR3 &scale)
	{
		DropPodPosition = start;//set the position
		//DropPodPosition.y = start.y + 10000.0;

		//set the target
		DropPodTarget = target;

		DropPodScale = scale;

		//calculate the direction we want
		DropPodHeading = target - DropPodPosition;

		D3DXVec3Normalize(&DropPodHeading, &DropPodHeading);

		DropPodVelocity = D3DXVECTOR3(0.0, -9.81, 0.0);
		DropPodDecelerate	= D3DXVECTOR3(0.0, 0.0, 0.0);
		ActiveDropPod = true;
		OpenPod = false;
		DropPodOnGround = false;
		DropPodElapsedTime = 0;

	}//end ActivateDropPod
	/////////////////////////////////////////////////////////////////////////////////////



	//--------------------------------------------------------------------
	//returns true if we are active
	//--------------------------------------------------------------------
	//bool DropPodActive(void){return ActiveDropPod;}



	//----------------------------------------------------------------------
	//this will return the pods render data needed to draw it
	//----------------------------------------------------------------------
	cDropPodRenderData GetDropPodRenderData(void)
	{
		cDropPodRenderData data;
		data.ElapsedTime	= DropPodElapsedTime;
		data.Pos		= DropPodPosition;
		data.Scale		= DropPodScale;
		return data;
	}//end GetDropPodRenderData
	///////////////////////////////////////////////////////////////////////


};//end class
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Usage

cDropPodSate *pod = NULL;
bool done = false;//if this is true we delete the element

D3DXMATRIX vp =  View * Projection;
D3DXMATRIX Scale;
D3DXMATRIX World;
cDropPodRenderData podrenderdata;
	
D3DXVECTOR4 meshcolour = D3DXVECTOR4(1,1,1,1);//Run-Time Check Failure #2 - Stack around the variable 'meshcolour' was corrupted.
float alpha= 1.0;

//to do inerate throught the list if the pods process returns true we remove the pod
	std::list<cDropPodSate>::iterator iter = DropPodManager.DropPods.begin();

	while( iter != DropPodManager.DropPods.end())// DropPodManager.DropPodIterator++)
	{
		pod = (cDropPodSate*)&iter;//this is bad but the complier does not complain
		done = iter->ProcessDropPod(timedelta);//this stops the error
		if(done)
		{
			//remove this element where done
			iter = DropPodManager.DropPods.erase(iter);
		}
		else
		{
			//we can render the pod
			BOOL atend = false;
			
			//get the render data
			podrenderdata = iter->GetDropPodRenderData();

			//increament the array
			iter++;

		}//end render pod


	}//end all valid droppods

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Share this post


Link to post
Share on other sites
Ohforf sake    2052
I fully agree with Washu but for the sake of understanding, here is what's going on.

 
pod = (cDropPodSate*)&iter;//this is bad but the complier does not complain
This is indeed bad. iter is of type std::list<cDropPodSate>::iterator, not of type cDropPodSate. You then take the address of it, &iter, which means that the compiler will place the iterator object on the stack and return the address of it. Then you cast that address, which is of type std::list<cDropPodSate>::iterator* to an address of type cDropPodSate* and use it to access the memory region on the stack, where the iterator resides, as if it were a cDropPodSate. This will of course give you nothing but junk. The reason why the compiler doesn't complain about this although it's really bad is that explicit cast: (cDropPodSate*) It tells the compiler no to worry because you really, really want this and you know what you are doing. Whenever you use such a cast on a pointer (and if it happens often, you really should rethink your design), you should make absolutely sure that you know what you are doing.

What you probably wanted is this:
pod = &(*iter);
iter is again of type std::list<cDropPodSate>::iterator. The * operator of iterator, *iter or iter.operator*(), is a custom overload that will give you a reference to the object that the iterator is referring to, which is a cDropPodSate. &(*iter) then takes the address of the object, that iter is referring to.

Also, you should always preincrement iterators (++iter;) instead of postincrementing them (iter++;).

Share this post


Link to post
Share on other sites
Washu    7829


Also, you should always preincrement iterators (++iter;) instead of postincrementing them (iter++;).

 

While not bad advice, it should be noted that most compilers will elide construction of the temporary as they will be smart enough to see that it is never used. As such, there is no real performance difference between post-increment and pre-increment on standard iterators in most cases (advanced debugging capabilities can add additional cost, but that is not something that matters when you're building in debug mode anyways).

Share this post


Link to post
Share on other sites
gonrogon    142

In addition to the other advices.

I suggest to never use the C-style type casting in a C++ program. When the C-style cast expression is encountered, the compiler attempts to run a set of cast expressions to find a suitable one.

explicit cast: http://en.cppreference.com/w/cpp/language/explicit_cast

As each high level casting fails, the reintepret_cast is applied. So that the compiler don't complaint about it.

reinterpret_cast: http://en.cppreference.com/w/cpp/language/reinterpret_cast

In C++, static_cast, dynamic_cast, reinterpret_cast, and const_cast are prefered instead of C-style casting operator.

If you use the static_cast (pod = static_cast<cDropPodSate*>(*iter)) the compilation fails reporting the problem. Anyway, as Ohforf sake wrote, in your code a cast is not necessary.

Edited by gonrogon

Share this post


Link to post
Share on other sites
ankhd    2304

Wow, I have some things to change.

 

Ohfors sake I did want this. pod = &(*iter); good advice to.

 

Gonrogon looks like I have some reading to do.

 

and Wash good advice too. I did have it as a vector but changed it when I was getting a crash to debug the effect.

 

I've also looked into using the std::remove_if(pods.begin(), pods.end(), predicate_function);

but I need to do rendering of the pod in the same while loop as done == false pods get rendered as well.

May be begin() can be replaced with inter and end() with inter++ but remove_if does no boundary checks hey.

 

Thanks.

Share this post


Link to post
Share on other sites
Bill Door    360

Regarding casting -- #gonrogon advice is sound. To add a bit, whenever you use a cast, any of the cast's but especially C-style casts, you are saying that you are smarter than the compiler. That's a risk that I don't like to take unless I am very confident. 

 

If I use a cast, it's because I tried without the cast and the compiler told me what I needed to do to get the cast that I wanted. The compiler is your friend.

Share this post


Link to post
Share on other sites
SeanMiddleditch    17565

While not bad advice, it should be noted that most compilers will elide construction of the temporary as they will be smart enough to see that it is never used.


While not a bad note, it's not true for most common debug builds with optimizations turned off. Since we generally like being able to debug something a little faster than a slideshow, it's common for game developers to pull a lot of tricks in order to avoid unnecessary overhead that an aggressive optimizer might otherwise eliminate.

I've also looked into using the std::remove_if(pods.begin(), pods.end(), predicate_function);
but I need to do rendering of the pod in the same while loop as done == false pods get rendered as well.
May be begin() can be replaced with inter and end() with inter++ but remove_if does no boundary checks hey.


remove_if doesn't actually remove anything. It moves all the to-be-removed items to the end of the container, and then returns an iterator to that end point. You can then iterate over the whole container, do what you need, and then erase all the items starting at the iterator it returned.

You can also implement this yourself easily enough and keep things to a single iteration.

Share this post


Link to post
Share on other sites
ankhd    2304

Hi again.

 

Trying to use remove_if with erase and I get _DEBUG_ERROR("vector erase iterator outside range");

 

I need extra params so I can render and process within remove_if. To do this one could use a function object.

 

but I can't get it to run what doe remove_if do if it cant remove any.

 

How would you detect if it did not remove(move to bottom of list).

 

can you do what Im tring to do that is process and render and remove at the same time.????

 

here is the code(code blocks doing strange things)


//-----------------------------------------------------------------------------------------

//this is our Function object used in remove_if we pass our self to

//we need to set the render values before passing in in

//------------------------------------------------------------------------------------------

class

 

cFunctionObject

{

public

 

:

D3DXMATRIX *View;

D3DXMATRIX *Projection;

D3DXMATRIX *LightView;

D3DXMATRIX *LightVolume;

Light *light;

D3DXVECTOR3 *lightdirw;

DrawableTex2D *shadowMap;

 

float *timedelta;

D3DXVECTOR3 *eye;

cDX10Mesh *m_DX10MeshDropPod;

cAnimationCollection *AnimationDropPod;

 

cFunctionObject(

void)

{

}

//end

 

/////////////////////////////////////////////////////////

~cFunctionObject(

void)

{

}

//end

 

////////////////////////////////////////////////////////////////

 

const cFunctionObject& cFunctionObject::operator=(const cFunctionObject& s)

{

View = s.View;

Projection = s.Projection;

LightView = s.LightView;

LightVolume = s.LightView;

light = s.light;

lightdirw = s.lightdirw;

shadowMap = s.shadowMap;

timedelta = s.timedelta;

eye = s.eye;

m_DX10MeshDropPod = s.m_DX10MeshDropPod;

AnimationDropPod = s.AnimationDropPod;

 

return *this;

}

 

 

 

 

//----------------------------------------------------------------------------------------------------

 

//A function object, or functor, is any type that implements operator(). This operator is referred to as

 

//the call operator or sometimes the application operator. The Standard Template Library uses function

 

//objects primarily as sorting criteria for containers and in algorithms.

 

//----------------------------------------------------------------------------------------------------

 

bool cFunctionObject::operator() (cDropPodSate &droppod)

{

 

bool done = droppod.ProcessDropPod(*timedelta);

 

if(done == false)

{

D3DXMATRIX vp = (*View) * (*Projection);

D3DXMATRIX Scale, Rotation;

D3DXMATRIX World;

cDropPodRenderData podrenderdata;

D3DXVECTOR4 meshcolour = D3DXVECTOR4(1,1,1,1);

//Run-Time Check Failure #2 - Stack around the variable 'meshcolour' was corrupted.

 

float alpha= 1.0;

 

//we can render the pod

BOOL atend =

false;

 

 

//get the render data

podrenderdata = droppod.GetDropPodRenderData();

AnimationDropPod->Update(

"Open", podrenderdata.ElapsedTime, FALSE, &atend);

 

 

//render the mesh

 

D3DXMatrixScaling( &Scale, podrenderdata.Scale.x, podrenderdata.Scale.y, podrenderdata.Scale.z);

//0.5f, 0.5f, 0.5f );

D3DXMatrixTranslation( &World, podrenderdata.Pos.x, podrenderdata.Pos.y, podrenderdata.Pos.z);

 

 

//we only align when we are not deployed

 

if(podrenderdata.StopAlignment == false)

{

 

//we align the pod to the direction its moving in

Rotation = AlignYupToDirection(podrenderdata.Pos, podrenderdata.Target);

World = Scale * Rotation * World;

}

 

else

{

 

//no rotation

World = Scale * World;

}

 

 

//render the static mesh or frames

m_DX10MeshDropPod->RenderAuto(&vp,

//veiw projection matrix

&World,

LightView,

LightVolume,

eye,

//D3DXVECTOR3 *eyepos,

light,

lightdirw,

//m_ParallelLight.dir,

meshcolour,

shadowMap,

alpha);

 

}

//end render pod

 

return done;//if its true it gets removed

}

//end operator()

 

//////////////////////////////////////////////////////////////////////////////////////////////////

 

//////////////////////////////////////////////////////////////////////////////////////////////////

 

 

 

 

 

 

//----------------------------------------------------------------------------------------

 

//must call it before using

 

//----------------------------------------------------------------------------------------

 

void SetFunctionObject(D3DXMATRIX *view,

D3DXMATRIX *projection,

D3DXMATRIX *lightView,

D3DXMATRIX *lightVolume,

Light *Light,

D3DXVECTOR3 *Lightdirw,

DrawableTex2D *shadowmap,

 

float *Timedelta,

D3DXVECTOR3 *Eye,

cDX10Mesh *dX10MeshDropPod,

cAnimationCollection *animationDropPod)

{

View = view;

Projection = projection;

LightView = lightView;

LightVolume = lightVolume;

light = Light;

lightdirw = Lightdirw;

shadowMap = shadowmap;

timedelta = Timedelta;

eye = Eye;

m_DX10MeshDropPod = dX10MeshDropPod;

AnimationDropPod = animationDropPod;

}

//end SetFunctionObject

 

////////////////////////////////////////////////////////////////////////////////////////////////

 

///////////////////////////////////////////////////////////////////////////////////////////////

 

};

//end class cFunctionObject

//////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

 

 

 

Used like this


//we are using a function object to pass to remove_if which will do the processing and remove them if function object returns true

cFunctionObject FunctionObject;

FunctionObject.SetFunctionObject(&View,

&Projection,

LightView,

LightVolume,

light,

lightdirw,

shadowMap,

&timedelta,

&eye,

m_DX10MeshDropPod,

AnimationDropPod);

 

 

//std::remove_if(DropPodManager.DropPods.begin(), DropPodManager.DropPods.end(), FunctionObject);

 

//the remove_if will go through the whole list and remove when pods process is true

DropPodManager.DropPods.erase(std::remove_if(DropPodManager.DropPods.begin(), DropPodManager.DropPods.end(), FunctionObject));

Share this post


Link to post
Share on other sites
ankhd    2304

Found the problem I forgot to add the end range for erase.

 

Like so.

DropPodManager.DropPods.erase(std::remove_if(DropPodManager.DropPods.begin(), DropPodManager.DropPods.end(), FunctionObject),

                                                         DropPodManager.DropPods.end());//this bit

 

 

Well all up that was worth the time in research thanks all.

 

Oh and it works fine can't see any slow down to this new bit of code to the first post's code loop.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this