“访问违规读取位置”访问全局向量时
-- 首先,我不知道如果我在命名空间下而不是在类或函数中声明该向量,是否可以将其称为“全局向量”。 --
我现在正在为我的应用程序编写一个简单的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
调用堆栈指向执行很多操作的行。我建议检查以下检查列表来追踪问题:
更新:既然您的问题已更新,这里有一个可能发生的新想法:
您的代码的简化版本是这样的:
如果 iGraphicsDriver 具有未经检查的值,则 drvT 可能保持未初始化状态。在这种情况下,createDevice() 调用可能会返回无效设备,进而在调用 getVideoDriver() 时返回无效视频驱动程序。
我建议您将 drvT 初始化为合理的值,例如:
这可以避免该问题。
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:
UPDATE: Now that your question was updated, here's a new idea what might be happening:
A simplified version of your code is this:
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:
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();
驱动程序获得无效对象。矢量没问题。
irrw::driver = irrw::device->getVideoDriver();
driver got invalid object. vector is ok.
我的猜测是 getTexture 失败了。
您确定 szFileName 将其定向到磁盘上实际存在的文件吗?尝试对完全限定路径进行硬编码,以查看当前工作目录是否存在问题。
像这样重写代码,使用调试器单步执行并检查所有值。确保 foo 实际上指向有效的某个地方,并确保由于向量而确实发生了访问冲突。
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.
正如 Frerich Raabe 所说,您在一行代码中执行多个操作,并且极有可能是
push_back
调用以外的其他操作生成了访问冲突。如果有帮助,您可以拆分语句以查看发生访问冲突的时间点。像这样拆分表达式应该可以让您确定问题所在。
编辑:修复了我的代码的问题。
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.Splitting up the expression like this should let you know for certain where the problem lies.
Edit: Fixed problems with my code.