Page 1 of 1

Help with exceptions

Posted: Fri Jan 11, 2008 12:31 am
by wizecoder
Hi I am working on a 2d pong game with irrlicht and visual studio 2008, i do not have any debugging errors but when it is done debugging and starts running in the output box it shows this:
Unhandled exception at 0x00411613 in Irrlicht Pong.exe: 0xC0000005: Access violation writing location 0x00000001.. Here is my code:

Code: Select all

#include <irrlicht.h>

using namespace irr;
using namespace core;
using namespace video;
using namespace gui;
using namespace scene;
using namespace io;

#pragma comment(lib, "Irrlicht.lib")

bool keys[irr::KEY_KEY_CODES_COUNT];

class MyEventReceiver : public IEventReceiver {
public:
	bool OnEvent(SEvent event) {
		if(event.EventType == irr::EET_KEY_INPUT_EVENT){
		keys[event.KeyInput.Key] = event.KeyInput.PressedDown;
		return false;
	}
	return false;
	}
};
struct PADDLE1
{
	ITexture* tex;
	s32 x, y;
};
int main(PADDLE1* p1)
{

	IrrlichtDevice *device = createDevice(EDT_DIRECT3D9);
	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();

	device->setWindowCaption(L"Irrlicht Pong Game");

                //not part of the code but this is where it messes up in front of the arrow->	p1->tex = driver->getTexture("../../Media/Player1paddle.jpg");
	p1->x = 100;
	p1->y = 200;
	
	while(device->run() && driver)
	{
		if (device->isWindowActive())
		{		
			u32 time = device->getTimer()->getTime();
			driver->beginScene(true, true, video::SColor(0,120,102,136));

			driver->draw2DImage(p1->tex,position2d<s32>(p1->x,p1->y));

			driver->endScene();
		}
	}
	device->drop();

	return 0;
}
PLEASE HELP I AM STUCK. :(

Re: Help with exceptions

Posted: Fri Jan 11, 2008 3:10 am
by rogerborg
wizecoder wrote: struct PADDLE1
{
ITexture* tex;
s32 x, y;
};
int main(PADDLE1* p1)
That's your problem right there. What your program's main function actually gets passed on program startup is this:

Code: Select all

main(int argc, char * argv[])
These function parameters are any strings that you passed to your program on the command line, preceeded by a string that's the name of the executable itself, so if you ran it as "foo.exe bar", your main() function would get passed two parameters: an argc (argument count) of 2, and an array of two strings (the argument values): argv[0] will be "foo.exe" and argv[1] will be "bar".

Even if you don't give any command line arguments, you always get passed the name of your executable in argv[0], so argc - i.e. the first parameter to your main function - will be an integer with a value of 1.

But you've told the compiler that parameter (an integer with a value of 1) is actually a pointer to a PADDLE1 structure (i.e. a memory address)! The compiler (fool that it is!) trusts that you know what you're doing, and it interprets that integer value as a pointer, even though it isn't one, and assigns that value to p1, which it thinks (because you told it so) is a pointer to a PADDLE1 structure.

So when execution reaches the line:

Code: Select all

p1->tex = driver->getTexture("../../Media/Player1paddle.jpg");
It finds that the value of p1 - a pointer, i.e. a memory address - is 1, as is the address of the first field that it points to. Memory address 1 is not a sane location to read from, let alone write to. Execution then falls over with a perfectly sensible error, an "access violation" which tells you that you're reading or writing an invalid memory location, and it even tells you the location, 0x00000001, the value of p1. Incidentally, in the code as you've posted it, the access violation is at 0x00000005, which is the value of 'p1', 1, plus the offset into the PADDLE1 structure of the field 'x', 4 bytes = memory address 5. Either way, you shouldn't be writing to there.

In short, you've lied to the compiler, and hurt its feelings. Poor compiler. There, there, I love you.

I don't really know what you're trying to do, but you definitely don't want to tell the compiler that your main() function is being passed a pointer to a PADDLE1 structure when it isn't. You most likely want to create an instance of a PADDLE1 on the stack or heap inside your main() function.

Suggestion: read some very, very basic C tutorials. Really, start with HelloWorld, and work your way up.

Posted: Fri Jan 11, 2008 3:50 am
by wizecoder
got it working, just got rid of the struct and did something else.

Posted: Fri Jan 11, 2008 11:47 am
by rogerborg
Do you understand why it didn't work before? ;)

Posted: Fri Jan 11, 2008 1:16 pm
by shogun
i do not have any debugging errors but when it is done debugging and starts running in the output box it shows this:
Um, are you sure you know how a debugger works?

Posted: Fri Jan 11, 2008 5:36 pm
by wizecoder
do you understand why it didnt work before
Well I am not totally sure what happened but when I moved

Code: Select all

PADDLE1* p1
out of main and put it into the code it said it was not initialized properly or something like that.

Posted: Fri Jan 11, 2008 6:32 pm
by Ico
Replace the beginning of your main function with something like this:

Code: Select all

int main(void) 
{ 
  PADDLE1 *p1 = new PADDLE1();
  ...
And at the end of your main function do the following:

Code: Select all

  ...
  delete p1;
}

You got the error message / warning as a pointer (variable name with star right before it) will just point to some random address instead of really contaning any value/content or pointing there.

Just using "datatype *varname;" is like buying a envelope and sending it without any recipient specified.

Try to find some simple tutorial on pointers in c/c++ - it's not that hard once you got the basics.