1

Windows 8 で Visual Studio 2012 と 2012 年 11 月の CTP を使用しています。
最適化を有効にして (/o2) C++ アプリケーションのリリース バージョンを実行すると、クラッシュします。
これは std::vector 内で発生します (ただし、ベクターを使用するのは初めてではありません)。
コードに足を踏み入れると、2回目にpush_backを実行したことがわかりました。

1197 if (this->_Mylast == this->_Myend)
1198     _Reserve(1);

_Reserve に従うと、1 からの count の値が 17656451 になり、後で再割り当てを呼び出すときにエラーが発生します (例外を無効にしています)。
デバッグモードで実行すると、すべて問題ありません。また、最適化を無効にしたリリース モードも正常に動作しています。
コンパイラがテストリリースだからでしょうか? 新しい機能の一部を使用しているため、元に戻して試すことができません。

編集:

これがコードの一部です。
私は2つの構造を持っています:

struct Subtile
{
    int sequenceId;
    AnimationSequenceState sequenceState;
    XMFLOAT2 position;
};

struct Tile
{
    //int type;
    bool visible;
    bool walkable;

    int x, y;
    int height;
    XMFLOAT2 position;
    float depth;
    XMVECTOR color;

    std::vector<Subtile> subtiles;
};

この関数は、lua ファイルからゲームの 2D マップを解析するときに、ループ内から呼び出されます。

HRESULT Map::parseTile(LuaState& l, int ix, int iy, XMFLOAT2 pos)
{
    Tile tile;

    tile.visible = l.getBoolField(-1, parsing::MapTileVisible, true);
    tile.walkable = l.getBoolField(-1, parsing::MapTileWalkable, true);
    tile.height = l.getIntField(-1, parsing::MapTileHeight, 0);

    bool sync = l.getBoolField(-1, parsing::MapTileSync, true);

    tile.x = ix;
    tile.y = iy;

    tile.position.x = pos.x;
    tile.position.y = pos.y;
    tile.depth = -static_cast<float>(ix + iy);
    tile.color = XMVectorSet(1.0f, 1.0f, 1.0f, 1.0f);

    l.pushString(parsing::MapTileSubtiles);
    l.getTable();
    {
        for(l.pushNil(); l.next(); l.pop())
        {
            Subtile subtile;
            subtile.sequenceId = l.toInt();
            _sequences[subtile.sequenceId].update(subtile.sequenceState);
            if(!sync)
            {
                subtile.sequenceState.elapsed = rand() % 1000; //一秒、適当に
            }
            tile.subtiles.push_back(subtile);
        }
    }
    l.pop();

    _tiles.push_back(tile); //second time crashes here

    return S_OK;
}

編集2:

コードのより完全な部分は次のとおりです-> LINK

私は問題をローカライズしようとしましたが、ここに私が見つけたものがあります。
113 行目のベクトルを削除しても効果がないように見えますが、18 行目のベクトル (およびそれを読み書きするコード) にコメントを付けると、何らかの形で解決されます。
ただし、297 行目からエラーが発生します。すべてのタイルを読み込んだ後、それらを並べ替えます。この問題は、288 ~ 292 の for ループをコメント化することで解消されます。
とにかく、私はまだ理由を理解していません。

4

2 に答える 2

1

私はついに犯人を見つけました。
XMVECTOR(DirectX Mathライブラリ)をTile構造に直接格納していました。

ドキュメントには、そうすることは避けるべきであると明示的に記載されています。
したがって、私が行ったことは、XMFLOAT4を保存し、値が必要なときにXMVECTORにロードすることです。

なぜアクセス違反が発生したのかはまだわかりませんが、ベクトルの内部表現(私の場合は__m128)、数学ライブラリの最適化、およびstd::vector内で発生する初期化されていない移動の組み合わせであると思います?

于 2012-12-18T03:07:24.563 に答える
1

私の水晶玉は、近くに保存されている別の変数に範囲外のバッファ アクセスがあり、std::vectorのメタデータを破損していることを示しています。

そこで、オーバークロックによるハードウェアの故障ではないかとマジック 8 ボールに尋ねたところ、「ありそうにない」という回答が返ってきました。

于 2012-12-05T20:58:54.237 に答える