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);
    //.........
}

そしてエラー:

Game.exe の 0x692804d6 で未処理の例外: 0xC0000005: アクセス違反の読み取り場所 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 を使用しています。

(コードが更新されました)

4

4 に答える 4

3

コールスタックは、多くのことを行う行を指しています。問題を追跡するために、次のチェックリストを確認することをお勧めします。

  1. irrw::driver は適切なオブジェクトを指していますか、それとも null/初期化されていないポインターですか?
  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 に初期化される可能性があるため、リリース ビルドでのみこれに気づきました。ただのクレイジーなアイデアです。

于 2009-10-15T12:54:33.150 に答える
0

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

ドライバーが無効なオブジェクトを取得しました。ベクトルは大丈夫です。

于 2009-10-15T13:14:13.887 に答える
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);
}
于 2009-10-15T13:57:52.360 に答える
0

Frerich Raabe が言ったように、1 行のコードで複数の操作を行っているため、呼び出し以外の何か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);

このように式を分割すると、問題がどこにあるかを特定できるはずです。

編集:私のコードの問題を修正しました。

于 2009-10-15T13:34:23.077 に答える