tags:

views:

398

answers:

5

Hello there,

-- First of all, I don't know whether the vector can be called as a "global vector" if I declared it under a namespace, but not in a class or function. --

I'm now writing a simple Irrlicht (http://irrlicht.sourceforge.net) wrapper for my game to make things simpler and easier, but recently I got an "Access violation reading location" error when trying to push_back a vector declared in the global scope.

Here is my code so far:

irrwrap.cpp:

namespace irrw
{
 //.........
 IrrlichtDevice *device;
 IVideoDriver *driver;
 irr::core::array<irr::video::ITexture*> TextureCollector;
 vector<int> TextureConnector;
 //.........
}

//..............

void irrInit(int iGraphicsDriver, int iWindowWidth, int iWindowHeight, int iScreenDepth, bool bFullScreen)
{
 E_DRIVER_TYPE drvT;
 if(iGraphicsDriver == GD_SOFTWARE)
  drvT = EDT_SOFTWARE;
 else if(iGraphicsDriver == GD_D3D8)
  drvT = EDT_DIRECT3D8;
 else if(iGraphicsDriver == GD_D3D9)
  drvT = EDT_DIRECT3D9;
 else if(iGraphicsDriver == GD_OPENGL)
  drvT = EDT_OPENGL;

 //..............

 irrw::device = createDevice(drvT, dimension2d<u32>(iWindowWidth, iWindowHeight), iScreenDepth, bFullScreen);
 irrw::driver = irrw::device->getVideoDriver();
 //..................
}

void irrLoadImage(irr::core::stringc szFileName, int iID, int iTextureFlag)
{
 //........
 irrw::TextureCollector.push_back(irrw::driver->getTexture(szFileName)); // the call stack pointed to this line
 irrw::TextureConnector.push_back(iID);
}

main.cpp:

//.........
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT)
{
 //.........
 irrInit(GD_OPENGL, 800, 600, 16, false);
 irrLoadImage("picture.jpg", 100, 1);
 //.........
}

and the error:

Unhandled exception at 0x692804d6 in Game.exe: 0xC0000005: Access violation reading location 0x00000558.

Now I really got no idea on how to fix the problem.

Any kind of help would be appreciated :)

Here are some prototypes:

 virtual ITexture* getTexture(const io::path& filename) = 0;
 typedef core::string<fschar_t> path; // under 'io' namespace
 typedef char fschar_t;
 typedef string<c8> stringc;
 typedef char c8;

Just FYI, I am using MSVC++ 2008 EE.

(CODE UPDATED)

+3  A: 

The call stack points to a line which does a lot of stuff. I suggest going over the following check list to trace down the problem:

  1. Does irrw::driver point to a proper object, or is it maybe a null/uninitialized pointer?
  2. What type of argument does irrw::driver->getTexture(..) take? Is it really a irr::core::stringc or something else (maybe a plain C string?).
  3. What is the value of 'szFileName'; can you print it (i.e. with printf or the like)? Maybe it's corrupted since the irr:core::stringc class did something funny.
  4. What is the return type of irrw::driver->getTexture(..) - does it really return a irr::video::ITexture* or does it maybe return something else (some kind of pointer wrapper)?
  5. What is the return value of the irrw::driver->getTexture(szFileName); call? Is it a proper texture?

UPDATE: Now that your question was updated, here's a new idea what might be happening:

A simplified version of your code is this:

E_DRIVER_TYPE drvT;
if(iGraphicsDriver == foo) // iGraphicsDriver is an int
        drvT = abc;
else if(iGraphicsDriver == bar)
        drvT = xyz;
// ... and so on ...

irrw::device = createDevice(drvT, ... );
irrw::driver = irrw::device->getVideoDriver();

It might be that drvT stays uninitialized in case iGraphicsDriver has an unchecked value. In that case, the createDevice() call might return an invalid device, which in turn returns an invalid video driver when calling getVideoDriver().

I suggest that you initialize drvT to something reasonably, like:

E_DRIVER_TYPE drvT = EDT_SOFTWARE;

This would avoid the problem.

FWIW, this bug might've gone unnoticed in the past since EDT_SOFTWARE might be a #define for 0. In debug builds, 'drvT' might automatically be initialized to 0, so you only noticed this in a release build. Just a crazy idea.

Frerich Raabe
I edited and improved my post. Please consider to improve your answer :).
djzmo
A: 

irrw::driver = irrw::device->getVideoDriver();

driver got invalid object. vector is ok.

EffoStaff Effo
A: 

As Frerich Raabe said, you're doing several operations in one line of code, and it's extremely likely that something other than the push_back call is generating the access violation. If it helps, you can split up your statement to see at which point the access violation is occurring.

io::path path_to_szFileName = szFileName;
assert(irrw::driver != NULL);
irr::video::ITexture* texture = irrw::driver->getTexture(path_to_szFileName);
irrw::TextureCollector.push_back(texture);

Splitting up the expression like this should let you know for certain where the problem lies.

Edit: Fixed problems with my code.

Josh Kelley
I tried your code, but the assert() passed, and the program stops with the call stack pointing to the same line (the push_back). Is that mean irrw::driver is initialized properly?
djzmo
REV: When I tried to split the push_back and the getTexture, the program stops at the getTexture line, and the "path_to_szFileName" variable's value in the "Autos" tab (bottom-left screen while debugging) goes RED (yes, the text color).
djzmo
I haven't really used MSVC in several years, so I don't know what RED means. I think that it might just mean that it recently changed. If getTexture is triggering the access violation, then you'll probably have to do some digging in Irrlicht's docs or source code to find out why.
Josh Kelley
A: 

My guess is that getTexture is failing.

Are you sure szFileName directs it to a file that actually exists on disk? Try hard-coding a fully qualified path to see if there's an issue with the current working directory.

Rewrite the code like this, step through with a debugger and check all the values. Make sure foo actually points somewhere valid, and make sure that the access violation is actually happening because of the vector.

void irrLoadImage(irr::core::stringc szFileName, int iID, int iTextureFlag)
{
        //........
        ITexture *foo = irrw::driver->getTexture(szFileName);
        irrw::TextureCollector.push_back(foo);
        irrw::TextureConnector.push_back(iID);
}
ajs410
I tried it, and the code stops at the "ITexture *foo" line. What should I do now?
djzmo
A: 

Hi guys, i ve got a similar problem while playing a game i get the following error and the game stops:

Error: Access violation at 0x004216ED (tried to read from 0x17468FEB), program terminated.

Does anybody know if there is a solution to this?

Many thanks,

Anne

anne