“访问违规读取位置”访问全局向量时

发布于 2024-08-07 08:18:52 字数 2205 浏览 3 评论 0原文

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

我现在正在为我的应用程序编写一个简单的 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。

(代码已更新)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

ぇ气 2024-08-14 08:18:52

调用堆栈指向执行很多操作的行。我建议检查以下检查列表来追踪问题:

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

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.

紫﹏色ふ单纯 2024-08-14 08:18:52

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

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

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

driver got invalid object. vector is ok.

蓦然回首 2024-08-14 08:18:52

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

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);
}
独守阴晴ぅ圆缺 2024-08-14 08:18:52

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

像这样拆分表达式应该可以让您确定问题所在。

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文