簡體   English   中英

訪問全局引導程序時的“訪問沖突讀取位置”

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

(代碼已更新)

調用堆棧指向執行很多工作的一行。 我建議翻閱以下檢查表以找出問題所在:

  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);的返回值是多少? 呼叫? 質地合適嗎?

更新:現在您的問題已更新,這是一個新的想法,可能會發生什么:

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

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM