Sign in to follow this  

[SDL] Help with mutexes or what?

This topic is 2589 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello Gamedev users!

I have a little problem with SDL mutexes or a general c++ problem.

I have Unhandled exception at 0x760a9617 (KernelBase.dll) in Backgammon v2 w thread.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x008bed58.. which I think is a bad memory location, but I can't seem to fix it.

Your help is appreciated!


Here is my code:

Main.cpp


#include "SDL_thread.h"
#include "SDL.h"
#include "SDL_mutex.h"
#include <stdio.h>
#include <stdlib.h>
#include <vector>

#include "functions.h"
#include "eventclass.h"


using namespace std;
SDL_mutex *list = NULL;
std::vector<gameEvent> eventlist(50),graphicslist(50),soundslist(50);


#include "sound.h"
#include "graphics.h"
#include "ai.h"
#include "imput.h"


int main(int argc, char *argv[])
{
gameEvent newEvent(1,"update screen","graphics");
eventlist.push_back(newEvent);
gameEvent neEvent(1,"play sounds","sounds");
eventlist.push_back(neEvent);

SDL_Thread *thread[4];
thread[0] = SDL_CreateThread(sound, NULL);
thread[1] = SDL_CreateThread(graphics, NULL);
thread[2] = SDL_CreateThread(ai, NULL);
thread[3] = SDL_CreateThread(imput, NULL);

while(true)
{}

for (int i =0;i<4;i++)
SDL_KillThread(thread[i]);
return 0;
}

and the two threads which I have problem with:

sounds.h

#include <stdio.h>
#include "eventclass.h"

int sound (void *data)
{
SDL_mutexP (list);
for (vector<gameEvent>::iterator itera = eventlist.begin(); itera!= eventlist.end();++itera)
if(itera->returnToWho() == "sounds")
{
printf("Sound event deleted\n");
eventlist.erase(itera);
}

SDL_mutexV (list);
return 0;
}


and gprahics.h

#include <stdio.h>

int graphics (void *data)
{
//seek new events
SDL_mutexP (list);
for (vector<gameEvent>::iterator iter = eventlist.begin(); iter!= eventlist.end();++iter)
if(iter->returnToWho() == "graphics")
{
printf("Graphic Event deleted\n");
eventlist.erase(iter);
}
SDL_mutexV (list);
return 0;
}

Share this post


Link to post
Share on other sites
Is that your actual code? You aren't initialising the mutex. SDL_KillThread is deprecated and should not be used. You invalidate iterators while traversing the vectors.

What does gameEvent look like?

Also, simplify. Comment out the AI and input threads until you solve the problem.

Also, multi-threading in C++ is a thankless task, more so if you are inexperienced. Are you sure it is worth it for a Backgammon game?

Share this post


Link to post
Share on other sites
Thanks for the replies!

It's a game for a school project and I just wanted to make it with threads. It should be the same without though.

Here is my gameEvent.h

#ifndef gameclass_h
#define gameclass_h
#include "string.h"
using namespace std;
class gameEvent
{
private:
int id;
string message,towho;
public:
int returnID ()
{
return id;
};
string returnMessage()
{
return this->message;
};
string returnToWho()
{
return this->towho;
};

gameEvent()
{
};
gameEvent(const int ID,const string MESSAGE,const string TOWHO)
{
this->id = ID;
this->message = MESSAGE;
this->towho = TOWHO;
};

~gameEvent(){};
};
#endif

I also changed the line of erasing the iterator so I wont loose it in both threads and initialised the mutex:

list = SDL_CreateMutex();
itera = eventlist.erase(itera);

One last question - How can I upload my files qust like in other topics rather than copy/paste the code myself?

Share this post


Link to post
Share on other sites
To keep iterators valid, you need to conditionally increment the iterator:

std::vector<Foo>::iterator it = foos.begin();
while(it != foos.end())
{
if(shouldRemove(*it))
{
it = foos.erase(it);
}
else
{
++it;
}
}


Otherwise, you can run out of the bounds when removing the final element (prove to yourself that this is the case, and that the above prevents this).

Alternatively, you can use the function std::remove_if() from the <algorithm> header. This is often referred to as the remove/erase idiom in C++, as it is actually more efficient than the naive loop above if you are removing lots of elements.

If the order of the vector is unimportant, consider the "swap and pop" trick. That is, swap the element you want removed with the one at the back, and then use pop_back(). This is very efficient if your object supports fast swapping, and is reasonably efficient even if it doesn't.

Using this I got a simple variant of your code to work. I notice that you are not initialising SDL, nor are you checking and handling errors. This will hurt you if you try to write real multi-threaded code.

Share this post


Link to post
Share on other sites

This topic is 2589 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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