Skip to main content
GameDev.net gamedev.net
🔒 Locked

SDL_Rect* Corruption of X value.

Started by lord_balron Jun 11, 2009 at 6:11 PM 7 replies 1.8k views
Original Post
lord_balron
lord_balron
I have 2 classes, an animation class and an animation manager class, for the blitting of the object I pass Animations.GetFrame() etc. What I've noticed is the animation is off, I found out that the x value of the SDL_Rect* is being corrupted. The y, w, and h values are what they were set to be. The SDL_Rect*'s are held in a vector after which the X value becomes corrupted. If I load it with 0 0 50 50 the values returned are 44 0 50 50 or 50 0 50 50 becomes 22 0 50 50. Any help would be greatly appreciated as this has been bugging me for some time.
rip-off
rip-off
Can you post a minimal example that exhibits the described behaviour?
rip-off
rip-off
Screenshots will not allow us to confirm what is going on.
lord_balron
lord_balron
Mkay - so...

For the animation manager we have.
class DLLFUNC MesaAnimManager	{	private:		std::string m_CurrentAnimation;	public:		MesaAnimManager();		~MesaAnimManager();		//Add a frame to the sequence		void AddAnimation(MesaAnim toAdd);		void SetAnimation(std::string newAnim);		//Retrieves the frame of the current animation		SDL_Rect* GetFrame();		//Set the frame of the current animation		void SetFrame(int FrameNumber);		//Retrieve the framerate of the current animation in milliseconds		int GetFrameRate();		//Set the framerate of the current animation in milliseconds		void SetFrameRate(int NewFrameRate);		void OnLoop();	//Updates the frame if timer is over framerate		void OnRelease(); //Releases and destroys all of the objects in the frame vector	protected:		std::vector<MesaAnim> Animations;	};


Then for the animation we have...

class DLLFUNC MesaAnim	{	private:		int m_CurrentFrame; //The current frame of the animation the animation is on		int m_FrameRate;	//When to loop the animation	public:		MesaAnim();		MesaAnim(int FrameRate, std::string ID, int StartFrame = 0);		~MesaAnim();		MesaTimer Timer;	//Keeps track of when to loop		std::string m_ID;		//Add a frame to the sequence		void AddFrame(int x, int y, int w, int h);		//Retrieves the current frame		SDL_Rect* GetFrame();		//Set the frame		void SetFrame(int FrameNumber);		//Retrieve the current framerate, in milliseconds		int GetFrameRate();		//Set the framerate in milliseconds		void SetFrameRate(int NewFrameRate);		void OnLoop();	//Updates the frame if timer is over framerate		void OnRelease(); //Releases and destroys all of the objects in the frame vector	protected:		std::vector<SDL_Rect*> Frames;	};


In the AddFrame functions we have

void MesaAnim::AddFrame(int x, int y, int w, int h)	{		SDL_Rect* toAdd = new SDL_Rect;		toAdd->h = h;		toAdd->w = w;		toAdd->x = x;		toAdd->y = y;		Frames.push_back(toAdd);		cout << toAdd->x << " " << toAdd->y << " " << toAdd->w << " " << toAdd->h << endl;	}


The Get function is
SDL_Rect* MesaAnim::GetFrame()	{		return Frames[m_CurrentFrame];	}


With the animation manager having
SDL_Rect* MesaAnimManager::GetFrame()	{		for (unsigned int i = 0; i < Animations.size(); i++)		{			if (Animations.m_ID == m_CurrentAnimation)			{				return Animations.GetFrame();			}		}	}


But what I've found out is that the data has been corrupted before seeing as when I check out the x value in Frames[m_CurrentFrame] I get a bad value.

This is in C++ just so you know.

If you need more I can put up whatever needed.
Litz
Litz
In your AddFrame function, you are creating a pointer to a SDL_Rect, and pushing him back to your vector of pointers. However, you aren't saving the original SDL_Rect anywhere, so as soon as the function ends, the original SDL_Rect will run out of scope, and you will basically have a bad pointer in your vector. Why don't you just use a vector instead?
rip-off
rip-off
Quote:
Original post by Litz
In your AddFrame function, you are creating a pointer to a SDL_Rect, and pushing him back to your vector of pointers. However, you aren't saving the original SDL_Rect anywhere, so as soon as the function ends, the original SDL_Rect will run out of scope, and you will basically have a bad pointer in your vector. Why don't you just use a vector instead?


Incorrect. The original pointer is allocated by new, so will be valid until it is passed to delete. It is unclear when the pointer is passed to delete, which may be a problem.

That said, the advice of storing a vector of SDL_Rect instances is still good, and might possibly be the solution to the OPs problems.

@lord_balron

The reason I suspect your code isn't working is due to the std::vector<> in MesaAnimManager. This vector is holding MesaAnim instances. The class MesaAnim has a destructor but does not appear to otherwise follow the rule of three. I think this is what is causing problems for you.

Changing the vector inside MesaAnim to hold instances and removing the destructor might fix this (provided that MesaTimer also respects the rule of three).

If the code still misbehaves, we would have to see more of the implementations of the various classes to give more advice.



doorMaster
doorMaster
I was wondering, did this solution fix your problem? I was having a very similar problem, and somehow alleviated it, but I cannot remember what I did to fix it, however I do want to know so I do not make my same mistake in the future :)
lord_balron
lord_balron
Mkay, sorry for the delayed response our router died this morning...

Well I'd like to confirm that switching to SDL_Rect instances fixed the issue, everything is working great.

Thanks for the help.

I'll have to post images of the project when we're finished it (Next week some time).

Topic Locked

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

Sign in to reply to this topic.