[SDL] Help with mutexes or what?

Started by
3 comments, last by rip-off 13 years, 5 months ago
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);
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;
}
Advertisement
new failed at that instruction address. You probably want to run in the debugger to see what's actually going on.
[TheUnbeliever]
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?
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?
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.

This topic is closed to new replies.

Advertisement