2009-10-15 84 views
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.

現在我真的不知道如何解決這個問題LEM。

任何形式的幫助,將不勝感激:)

下面是一些原型:

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。

(CODE修訂版)

+0

irrw :: driver-> getTexture(sFileName)是否有可能產生AV而不是push_back? 「讀取地址0x00000558」看起來可能會追逐一個NULL指針;是irrw ::驅動程序初始化? – 2009-10-15 12:47:30

+0

是的。我編輯了我的帖子並添加了一些額外的代碼行,以顯示irrw :: driver已經初始化。你在說什麼這個'AV'? – 2009-10-15 13:08:46

+0

AV =訪問衝突 – 2009-10-15 13:29:00

回答

3

調用堆棧點到線,做了很多的東西。我建議通過以下檢查列表來追查問題:

  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)的返回值;呼叫?這是一個適當的質地?

UPDATE:現在,你的問題進行了更新,這裏有一個新的想法可能發生的事情:

你的代碼的簡化版本是這樣的:

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; 

這將避免此問題。因爲EDT_SOFTWARE可能是0的#define,所以這個bug在過去可能沒有被注意到。在調試版本中,'drvT'可能會自動初始化爲0,所以你只在發佈版本中注意到這一點。只是一個瘋狂的想法。

+0

我編輯和改進了我的文章。請考慮改善你的答案:)。 – 2009-10-15 13:13:07

0

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

驅動程序得到無效的對象。矢量是好的。

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

像這樣拆分表達式應該讓你知道問題出在哪裏。

編輯:修復了我的代碼問題。

+0

我試過你的代碼,但assert()通過了,程序停止時調用堆棧指向同一行(push_back)。這是否意味着irrw :: driver被正確初始化? – 2009-10-15 14:00:58

+0

REV:當我試圖拆分push_back和getTexture時,程序停在getTexture行,並且「Autos」選項卡中的「path_to_szFileName」變量的值(調試時左下角的屏幕)變爲RED(是的,文本顏色)。 – 2009-10-15 14:04:29

+0

我好幾年沒有真正使用過MSVC,所以我不知道RED的意思。我認爲這可能意味着它最近發生了變化。如果getTexture觸發了訪問衝突,那麼您可能需要在Irrlicht的文檔或源代碼中進行挖掘以找出原因。 – 2009-10-15 14:14:43

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); 
} 
+0

我試過了,代碼停在「ITexture * foo」行。我現在應該怎麼做? – 2009-10-15 14:07:55