繁体   English   中英

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

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

-首先,如果我在命名空间下而不是在类或函数中声明了该向量,则不知道该向量是否可以称为“全局向量”。 -

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

到目前为止,这是我的代码:

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

和错误:

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

现在我真的不知道如何解决该问题。

任何帮助,将不胜感激:)

以下是一些原型:

    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;

仅供参考,我正在使用MSVC ++ 2008 EE。

(代码已更新)

调用堆栈指向执行很多工作的一行。 我建议翻阅以下检查表以找出问题所在:

  1. irrw :: driver是否指向正确的对象,或者它可能为空/未初始化的指针?
  2. irrw :: driver-> getTexture(..)采用哪种类型的参数? 真的是irr :: core :: stringc还是其他东西(也许是纯C字符串?)。
  3. szFileName的值是什么? 您可以打印它(即使用printf之类的东西)吗? 由于irr:core :: stringc类做了一些有趣的事情,所以它可能已损坏。
  4. irrw :: driver-> getTexture(..)的返回类型是什么?它真的返回irr :: video :: ITexture *还是返回其他内容(某种指针包装器)?
  5. irrw :: driver-> getTexture(szFileName);的返回值是多少? 呼叫? 质地合适吗?

更新:现在您的问题已更新,这是一个新的想法,可能会发生什么:

您的代码的简化版本是这样的:

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

如果iGraphicsDriver具有未检查的值,则drvT可能保持未初始化状态。 在这种情况下,createDevice()调用可能返回无效的设备,当调用getVideoDriver()时,该设备又返回无效的视频驱动程序。

我建议您将drvT初始化为合理的值,例如:

E_DRIVER_TYPE drvT = EDT_SOFTWARE;

这样可以避免该问题。

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

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

驱动程序得到无效的对象。 矢量还可以。

正如Frerich Raabe所说,您正在一行代码中执行多项操作,并且很可能除push_back调用之外的其他操作都会导致访问冲突。 如果有帮助,您可以拆分语句以查看发生访问冲突的时间。

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

像这样拆分表达式可以使您确定问题出在哪里。

编辑 :修复了我的代码问题。

我的猜测是getTexture失败了。

您确定szFileName将其定向到磁盘上实际存在的文件吗? 尝试对完全限定的路径进行硬编码,以查看当前工作目录是否存在问题。

像这样重写代码,逐步调试器并检查所有值。 确保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