views:

303

answers:

2

I have a std::map declared thusly in a legacy MFC application:

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 is populated when the app loads by looping through a table and creating an instance of CNutrientInfo and then inserting it into the std:map like:

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

The std::map now contains a list of the nutrients that have been defined by the database. At some point a user can add a new nutrient to this list and it checks to see if what the user is adding already exists in the list. It does that check like:

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++;
}

Or at least it's supposed to. When the function actually gets called it never advances past the initial line of the while loop. Placing a breakpoint there simply shows that the line in question is called over and over and never advances beyond it, which hangs the app. If you step into the actual comparison it compares correctly and then returns to the while loop line. Stepping in again to advance into the body of the loop simply returns to the while loop line. This same logic is used elsewhere in the app with no trouble so I'm stumped as to what's going on in this case. I've re-written the logic above using a for-loop and it works just fine, so it's not like I can't work around it, but C++ isn't my strongest language and as this is a legacy app that I'm trying to help support, I'd really like to learn and understand WHY this is doing what's it's doing for future reference. Plus, since the logic works elsewhere and not here perhaps there's an underlying cause that is what actually needs to be addressed.

Any suggestions or thoughts on this would be greatly appreciated.

Thanks in advance.

+4  A: 

Is your example actually pasted from the source? Maybe it looks more like:

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++;
}
Michael Burr
I thought you may be right. but on checking again what @Scott says, he forcibly stepped into actual comparison and it returned to the loop. I'm just wondering if semicolon is the issue.
aJ
@aJ - wouldn't that be the expected (if undesired) behavior if there were a semi-colon immediately following the `while` controlling expression?
Michael Burr
Fully agreed. If there is a semicolon then definitely application will hang. I was just wondering about his sentence, in which he says, stepping forcibly into the loop is returning to the loop.
aJ
Such a classic error. One of the reasons I like Python.
Mark Ransom
Yes, it's a case of seeing what you expect to see and not seeing what's actually there. I'm embarrassed to admit that there was a semi-colon at the end of the line. Hard to believe I get paid to do this sometimes.And just to clear up, I stepped into the actual != comparison and when that comparison returned, it returned me to the while loop line, as you'd expect, but then the next step failed to move on into the body of the loop, because of the semi-colon.
Scott
Oh - I read that as just stepping again, which happens to step right beck into the comparison.
Michael Burr
Oh, and thanks to all who contributed/commented. It's very much appreciated.
Scott
@Scott - if a C/C++ programmer says that's never happen to him, then he either hasn't been programming for long or he's lying.
Michael Burr
@Michael Burr, Bingo!!! You are right.
aJ
But, it is an example of why it's a really, really good idea to copy-n-paste these kinds of code bits.
Michael Burr
Very true re:copy/paste. Which is what amazes me even more as I re-typed the darn code and still didn't see the semi-colon. Guess that's why writers have editors, proofing your own prose is prone to gaffes.
Scott
A: 

There is nothing in the code posted above which can cause that behavior. Are you sure that you are incrementing some other iterator inside the loop or may be there two iterators with the same name (one inside the loop) with different scopes and you are incrementing the wrong iterator ? If this is not the case, then only other alternative I could see is to note down the value of m_NutrientInfoMap.end() and check why ++iter is not evaluating into that value.

Naveen