[英]“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。
(代码已更新)
调用堆栈指向执行很多工作的一行。 我建议翻阅以下检查表以找出问题所在:
更新:现在您的问题已更新,这是一个新的想法,可能会发生什么:
您的代码的简化版本是这样的:
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.