5

私は VS2012 で C++ を独学してきましたが、本当に頭を悩ませる何かに出くわしました。オブジェクトを作成して別のオブジェクトへの参照を追加すると、オブジェクトが破損するか何かが発生するようです。nullではありません(null ポインター チェックのすべての組み合わせでこれを確認できます) が、その内容はファンキーであり、そのメンバーの 1 つにアクセスしようとすると、"0xC0000005: アクセス違反の読み取り場所 0xCCCCCCE8" が発生します。

ここに画像の説明を入力

私のプログラムの要点は、Tile オブジェクトの 2D ベクトルがあり、それぞれが Site への参照を持っている可能性があるということです。サイトを持つタイルの draw() 関数を使用すると、文明が属する色でそのサイトを描画しようとします。

ワールド生成:

std::vector<std::vector<Tile>> world;
// ... vector is sized ...
// Populate world with tiles
for (int h=0; h<height; h++) {
    for (int w=0; w<width; w++) {
        Tile t(PLAINS);
        world[h][w] = t;
    }
}

文明が作成されると、単純な首都が作成され、それへの参照が指定された x、y のタイルに配置されます。

void Game::createCivilisation(std::string name, sf::Color colour, int x, int y) {

    // Create the civ
    Civilisation civ(name, colour);

    // Create their capital and link it up
    Site capital("Capital", year, &civ);  // when I comment these five lines out
    civ.capital = &capital;               // the program doesn't crash, so I know
    civ.sites.push_back(capital);         // that the dodgy site originates here.

    // Add capital to tile
    world[y][x].site = &capital;
    capital.location = &world[y][x];
}

ただし、タイルの draw() 関数が呼び出されるまでに、サイトのメンバーにアクセスしようとすると終了します。これはただ一つの文明の場合です。

if (site != nullptr) { // have also tried (site) (site!=0) (site!=NULL)
    sf::CircleShape s(tileWidth*0.5);
    s.setFillColor(site->civilisation->colour);  // womp womp

上の画像は提供されたデバッグ情報です。ご覧のとおり、すべてゴミです。「資本」は何十億ものゴミの列になり、すべてが間違っていて、他のオブジェクトへの参照もすべてなくなっています。資本サイトのリンクをコメントアウトすると

関連するコードのスニペットをすべて提供したと思います(簡潔にするため/彼女の喜びのために)。私はこれに数時間取り組んできましたが、困惑しました。すべてのインデックスは正しいはずです。createCivilisation() で生成されたサイトは間違いなく存在する唯一のサイトです。

4

2 に答える 2