итератор std :: map не повторяется в приложении MFC - PullRequest
0 голосов
/ 21 апреля 2009

У меня есть std :: map, объявленная таким образом в устаревшем приложении MFC:

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 ++ не самый сильный мой язык, и это устаревшее приложение, которое я Пытаюсь помочь поддержать, я бы очень хотел узнать и понять, ПОЧЕМУ это делает то, что он делает для дальнейшего использования. Кроме того, поскольку логика работает в другом месте, а не здесь, возможно, есть причина, которая действительно должна быть устранена.

Будем весьма благодарны за любые предложения или мысли по этому поводу.

Заранее спасибо.

Ответы [ 2 ]

3 голосов
/ 21 апреля 2009

Ваш пример действительно вставлен из источника? Может быть, это выглядит как:

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++;
}
0 голосов
/ 21 апреля 2009

В приведенном выше коде нет ничего, что могло бы вызвать такое поведение. Вы уверены, что увеличиваете какой-то другой итератор внутри цикла или может быть два итератора с одинаковым именем (один внутри цикла) с разными областями действия, и вы увеличиваете неправильный итератор? Если это не так, то единственная альтернатива, которую я видел, - записать значение m_NutrientInfoMap.end () и проверить, почему ++ iter не оценивает это значение.

...