0

レガシーMFCアプリケーションでこのように宣言された std::map があります。

typedef std::map<long, CNutrientInfo> NUTRIENT_INFO_MAP;
typedef NUTRIENT_INFO_MAP::const_iterator NUTRIENT_INFO_ITER;
typedef NUTRIENT_INFO_MAP::value_type NUTRIENT_INFO_PAIR;
static NUTRIENT_INFO_MAP m_NutrientInfoMap;

m_NutrientInfoMap は、テーブルをループして CNutrientInfo のインスタンスを作成し、次のように std:map に挿入することによって、アプリが読み込まれるときに設定されます。

m_NutrientMapInfo.insert(NUTRIENT_INFO_PAIR(nutrient.GetId(), nutrient));

std::map には、データベースによって定義された栄養素のリストが含まれるようになりました。ある時点で、ユーザーがこのリストに新しい栄養素を追加すると、ユーザーが追加しようとしているものが既にリストに存在するかどうかがチェックされます。それは次のようにチェックします:

NUTRIENT_INFO_ITER iter = m_NutrientInfoMap.begin();
while (iter != m_NutrientInfoMap.end())
{
    m = (*iter).second;
    if (_stricmp(m.GetFullName().c_str(), name.c_str()) == 0)
    {
        return m;
    }
    iter++;
}

または、少なくともそうするはずです。関数が実際に呼び出されると、while ループの最初の行を超えて進むことはありません。そこにブレークポイントを配置すると、問題の行が何度も呼び出され、それを超えて進まないことが示され、アプリがハングします。実際の比較にステップインすると、正しく比較され、while ループ行に戻ります。再びステップインしてループの本体に進むと、単純に while ループの行に戻ります。これと同じロジックがアプリの他の場所でも問題なく使用されているため、この場合何が起こっているのかわかりません。for ループを使用して上記のロジックを書き直したところ、問題なく動作するので、回避できないわけではありませんが、C++ は私の最強の言語ではありません。これはレガシー アプリであるため、サポートを手伝おうとしています、私は' 今後の参考のために、なぜこれが何をしているのかを学び、理解したいと思っています。さらに、ロジックはここではなく他の場所で機能するため、実際に対処する必要がある根本的な原因がある可能性があります。

これに関する提案や考えは大歓迎です。

前もって感謝します。

4

2 に答える 2

3

あなたの例は実際にソースから貼り付けられていますか? 多分それはもっと似ています:

while (iter != m_NutrientInfoMap.end());   // <== note the semi-colon
{
    m = (*iter).second;
    if (_stricmp(m.GetFullName().c_str(), name.c_str()) == 0)
    {
        return m;
    }
    iter++;
}
于 2009-04-21T16:43:44.197 に答える
0

上記のコードには、その動作を引き起こす可能性のあるものは何もありません。ループ内で他のイテレータをインクリメントしていることは確かですか、それとも同じ名前の 2 つのイテレータ (ループ内に 1 つ) が異なるスコープであり、間違ったイテレータをインクリメントしている可能性がありますか? これが当てはまらない場合、m_NutrientInfoMap.end() の値を書き留めて、++iter がその値に評価されない理由を確認することしかできません。

于 2009-04-21T17:08:24.213 に答える