- 首先,我不知道如果我在名称空间下声明它,而不是在类或函数中,它是否可以被称为“全局向量”。 -
我现在正在为我的游戏编写一个简单的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。
(代码更新)
答案 0 :(得分:3)
调用堆栈指向一行,它可以执行很多操作。我建议查看以下检查清单以追查问题:
更新:现在你的问题已经更新了,这里有一个新想法可能会发生什么:
您的代码的简化版本是:
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);
}