1

我在 Windows 8 和 2012 年 11 月 CTP 上使用 Visual Studio 2012。
当我在启用优化 (/o2) 的情况下运行我的 c++ 应用程序的发布版本时,它会崩溃。
它发生在 std::vector 内(虽然不是我第一次使用向量)。
进入代码我发现我第二次执行 push_back 时,在这里:

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

如果我遵循_Reserve,则从1开始的计数值变为17656451,导致稍后在调用重新分配时出错(我禁用了异常)。
在调试模式下运行时一切正常。禁用优化的发布模式也运行良好。
会不会是因为编译器是测试版?我正在使用一些新功能,所以我无法切换回来尝试。

编辑:

这是代码的一部分。
我有两个结构:

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

我的水晶球显示您在附近存储的另一个变量中具有超出范围的缓冲区访问权限,这会破坏std::vector的元数据。

然后我问魔8球会不会是超频导致的硬件故障,得到的回答是“不太可能”。

于 2012-12-05T20:58:54.237 回答
1

我终于找到了罪魁祸首。
我将 XMVECTOR(DirectX 数学库)直接存储在 Tile 结构中。

该文档明确指出应避免这样做。
所以我所做的是存储一个 XMFLOAT4 并在需要该值时将其加载到 XMVECTOR 中。

我仍然不明白为什么它会出现访问冲突,但我想是向量的内部表示(在我的例子中是 __m128)、数学库的优化和 std::vector 内部发生的未初始化移动的组合?

于 2012-12-18T03:07:24.563 回答