0

_transaction は、次のように宣言された、私のクラスのプライベート メンバー変数です。

public:
    typedef stdext::hash_map<wchar_t*, MyClass*, ltstr> transaction_hash_map; 
private:
    transaction_hash_map _transactions;

クリーンアップ中に、このリストを反復処理して、まだ解放されていないオブジェクトを解放しようとしています。ただし、ここのfor行でAV を取得しています。

for (transaction_hash_map::const_iterator it = _transactions.begin(); it != _transactions.end(); it++)
{   
            MyClass* item = (MyClass*)it->second;

    if (item != NULL)
    {
        item->End();
        delete item;
    }       
}

Re: ltstr とは何ですか?

private:
    struct ltstr
    {
        enum
        {
            bucket_size = 8,
            min_buckets = 16
        };

        bool operator()(wchar_t* s1, wchar_t* s2) const
        {
            return wcscmp( s1, s2 ) < 0;
        }

        size_t operator()(wchar_t *s1) const
        {
            size_t  h = 0;

            wchar_t *p = const_cast<wchar_t*>(s1);
            wchar_t zero = L'\0';

            while ( *p != zero ) h = 31 * h + (*p++);

            return h;
        }
    };

スタックは、begin() メソッド内に表示されます。何か案は?

4

3 に答える 3

0

forループの後に必ず_transactions.clear()を呼び出してください。

于 2009-09-30T01:48:42.930 に答える
0

私が考えることができる1つの考えられることは、hash_mapを反復処理しようとする前に、クラスが他の場所ですでに削除されているため、begin()がガベージで動作することです。チェックする価値があります...

また、wchar_t *はどのように割り当て/解放されますか?あなたが示したコードはそれらを扱っていないようです。それがループでどのように問題を引き起こすかはわかりませんが、検討する価値があります。

(MyClass*)マイナーなことの1つ-キャストは必要ありません。hash_mapの値はとにかくその型でなければならないので、明示的なキャストでそれらをバイパスするよりも、コンパイラに型チェックを強制させる方が良いでしょう。ただし、ここでは違いはありません。

于 2009-09-29T21:00:55.427 に答える
0

私が理解しているように、まだ削除されていない可能性のある「残りの」アイテムについて、ポインターを NULL に対してチェックしています。しかし、クリーンアップ ステージの前に削除する項目については、ポインターを NULL に設定しますか?

オブジェクトを削除しても、ポインターは自動的に NULL に設定されないことに注意してください。そうしないと、同じオブジェクトを 2 回削除しようとしている (if ステートメントが常に true になるため) と、アクセス違反が発生する可能性があります。

以下のコードは、二重削除を引き起こす例です。ポインターを NULL に設定する行のコメントを外すと、修正できます。


#include <cstddef>

struct Item {};

int main()
{
  Item * p = new Item();
  delete p;

  //If you don't make the pointer null...
  //p = NULL;

  if (p != NULL)
      //You delete the object twice.
      delete p;
}

編集: for行で正確にエラーが発生しているようです。だから私は疑問に思っています...

どうやら、データ型としてMyClassポインターを持つハッシュ テーブルである_transactionsメンバーを含むMyClassがあるようです。クリーンアップ コードがMyClassのメンバー関数内で実行される場合、反復している_transactionsを所有するMyClassインスタンスを(何らかの理由で) 削除している可能性はありますか?

この場合、このオブジェクトが存在しないため、 for内のit++ステートメントでエラーが発生する可能性があります。(当然、削除自体のように、エラーは別の場所にもある可能性があります。)

于 2009-09-29T20:30:51.767 に答える