简体   繁体   English

访问全局引导程序时的“访问冲突读取位置”

[英]“Access violation reading location” while accessing a global vector

-- 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. 我现在正在为我的游戏编写一个简单的Irrlicht( http://irrlicht.sourceforge.net )包装器,以使事情变得更简单,更轻松,但最近在尝试push_back在其中声明的向量时遇到“访问冲突读取位置”错误全球范围。

Here is my code so far: 到目前为止,这是我的代码:

irrwrap.cpp: 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: 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. 仅供参考,我正在使用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: 我建议翻阅以下检查表以找出问题所在:

  1. Does irrw::driver point to a proper object, or is it maybe a null/uninitialized pointer? irrw :: driver是否指向正确的对象,或者它可能为空/未初始化的指针?
  2. What type of argument does irrw::driver->getTexture(..) take? irrw :: driver-> getTexture(..)采用哪种类型的参数? Is it really a irr::core::stringc or something else (maybe a plain C string?). 真的是irr :: core :: stringc还是其他东西(也许是纯C字符串?)。
  3. What is the value of 'szFileName'; szFileName的值是什么? can you print it (ie with printf or the like)? 您可以打印它(即使用printf之类的东西)吗? Maybe it's corrupted since the irr:core::stringc class did something funny. 由于irr:core :: stringc类做了一些有趣的事情,所以它可能已损坏。
  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)? irrw :: driver-> getTexture(..)的返回类型是什么?它真的返回irr :: video :: ITexture *还是返回其他内容(某种指针包装器)?
  5. What is the return value of the irrw::driver->getTexture(szFileName); 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. 如果iGraphicsDriver具有未检查的值,则drvT可能保持未初始化状态。 In that case, the createDevice() call might return an invalid device, which in turn returns an invalid video driver when calling getVideoDriver(). 在这种情况下,createDevice()调用可能返回无效的设备,当调用getVideoDriver()时,该设备又返回无效的视频驱动程序。

I suggest that you initialize drvT to something reasonably, like: 我建议您将drvT初始化为合理的值,例如:

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. FWIW,由于EDT_SOFTWARE可能是0的#define,因此该错误在过去可能没有引起注意。在调试版本中,'drvT'可能会自动初始化为0,因此您仅在发行版本中注意到了此错误。 Just a crazy idea. 只是个疯狂的主意。

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

driver got invalid object. 驱动程序得到无效的对象。 vector is ok. 矢量还可以。

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. 正如Frerich Raabe所说,您正在一行代码中执行多项操作,并且很可能除push_back调用之外的其他操作都会导致访问冲突。 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. 编辑 :修复了我的代码问题。

My guess is that getTexture is failing. 我的猜测是getTexture失败了。

Are you sure szFileName directs it to a file that actually exists on disk? 您确定szFileName将其定向到磁盘上实际存在的文件吗? 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. 确保foo实际指向有效的地方,并确保由于向量而导致访问冲突实际上正在发生。

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM