0

次のようなデストラクタがあります。

Tilemap::~Tilemap(void)
{
    if(width>0 && height > 0)
    {
        for (int x = 0; x < getMapWidth(); x++)
        {
            for (int y = 0; y < getMapHeight(); y++)
            {
                if(getTileAtPoint(x,y)->isInteractable())
                {
                    delete getTileAtPoint(x,y)->getInteractable();
                }
            }
        }

        SAFE_DELETE_ARRAY(tileArray);
    }

    return;
}

SAFE_DELETE_ARRAY() は、次のような単なるマクロです。

#define SAFE_DELETE_ARRAY(ptr) { if(ptr) { delete [](ptr); (ptr)=NULL; } }

tileArray は、インタラクティブなオブジェクトを含むタイルを含む、動的に割り当てられる配列です。その宣言は次のようになります。

tileArray = new Tile[mapWidth*mapHeight];

コードの二重 for ループ セクションを削除して、これをそのままにしておくと、次のようになります。

Tilemap::~Tilemap(void)
{
    if(width>0 && height > 0)
    {
        SAFE_DELETE_ARRAY(tileArray);
    }
}

宣言した対話可能なオブジェクトが削除されていないため、メモリ リークが発生します。ただし、二重の for ループを離れると、コードは for ループを正常に通過しますが、SAFE_DELETE_ARRAY でクラッシュし、次のエラー メッセージが表示されます。

Spaceship.exe の 0x008927CC で未処理の例外: 0xC0000005: アクセス違反の読み取り場所 0xFEEEFEEE。

これを修正する方法を知っている人はいますか?

4

1 に答える 1

1

非常に単純なパターン: タイル オブジェクトのデストラクタに、Interactable オブジェクトがある場合はそれらを削除させます。そうすれば、タイルを削除すると自動的にクリーンアップされるため、外部でこれについて心配する必要はありません。

または、Tile クラスによって参照されるオブジェクトに対して、生のポインターの代わりにある種のスマート ポインターを使用します。

于 2013-06-14T22:39:59.750 に答える