-- 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 f开发者_如何学JAVAschar_t;
typedef string<c8> stringc;
typedef char c8;
Just FYI, I am using MSVC++ 2008 EE.
(CODE UPDATED)
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:
- Does irrw::driver point to a proper object, or is it maybe a null/uninitialized pointer?
- What type of argument does irrw::driver->getTexture(..) take? Is it really a irr::core::stringc or something else (maybe a plain C string?).
- 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.
- 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)?
- 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.
irrw::driver = irrw::device->getVideoDriver();
driver got invalid object. vector is ok.
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);
}
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.
精彩评论