访问全局向量时“访问冲突读取位置”

时间:2009-10-15 12:40:22

标签: c++ irrlicht

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

我现在正在为我的游戏编写一个简单的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。

(代码更新)

4 个答案:

答案 0 :(得分:3)

调用堆栈指向一行,它可以执行很多操作。我建议查看以下检查清单以追查问题:

  1. irrw :: driver是否指向正确的对象,或者它可能是null /未初始化的指针?
  2. irrw :: driver-&gt; getTexture(..)采用什么类型的参数?它真的是一个irr :: core :: stringc或其他东西(也许是普通的C字符串?)。
  3. 'szFileName'的价值是多少;你可以打印它(即用printf等)吗?也许它已经损坏了,因为irr:core :: stringc类做了一些有趣的事。
  4. irrw :: driver-&gt; getTexture(..)的返回类型是什么 - 它真的返回一个irr :: video :: ITexture *还是它可能返回别的东西(某种指针包装器)?
  5. irrw :: driver-&gt; getTexture(szFileName)的返回值是多少;呼叫?这是一种合适的质地吗?
  6. 更新:现在你的问题已经更新了,这里有一个新想法可能会发生什么:

    您的代码的简化版本是:

    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,所以你只在发布版本中注意到这一点。只是一个疯狂的想法。

答案 1 :(得分:0)

irrw :: driver = irrw :: device-&gt; getVideoDriver();

驱动程序获得无效对象。矢量没问题。

答案 2 :(得分:0)

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

将这样的表达式拆分可以让您知道问题所在。

修改:修复了我的代码问题。

答案 3 :(得分:0)

我的猜测是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);
}