[英]“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.