代码奇怪的行为

时间:2015-03-14 16:31:20

标签: c++

我看到我的部分代码没有按预期工作。它不会进入if语句并在应该出错时给出错误。我试图检查代码,发现一些非常奇怪的东西。当我在for循环中添加cout << i进行检查时,它开始运行良好。任何人都可以解释它有什么问题吗?注意:airports是机场对象的vectorAirport::getName()将其名称返回为string

string name = "smth";
//this is the loop with unexpected behaviour
for (int i = 0; i < airports.size(); i++)
{
    //when the following line is taken outside the comment, it works well:
    //cout << i;
    if (isEqualNoCaseSense(name, airports[i].getName()))
    {
        cout << "Could not create airport " << name << ". It already exists." << endl;
        return;
    }
}

我用来比较没有区分大小写的字符串的函数:

bool isEqualNoCaseSense(string str1, string str2)
{
if (str1.size() != str2.size())
    return false;
char *lowerStr1 = new char[str1.size()];
char *lowerStr2 = new char[str2.size()];
for (int i = 0; i < str1.size(); i++)
{
    lowerStr1[i] = tolower(str1[i]);
    lowerStr2[i] = tolower(str2[i]);
}
if (strcmp(lowerStr1, lowerStr2) == 0)
{
    delete[] lowerStr1;
    delete[] lowerStr2;
    return true;
}
else
{
    delete[] lowerStr1;
    delete[] lowerStr2;
    return false;
}
}

编辑:更正比较功能会修复它,但我仍然想知道为什么cout << i修复它

2 个答案:

答案 0 :(得分:3)

问题是你还没有终止你的字符串,但如果你只是写一个合理的函数它会正常工作:

bool isEqualNoCaseSense(const string& str1, const string& str2)
{    
    if (str1.size() != str2.size())
        return false;
    for (int i = 0; i < str1.size(); ++i)
        if (tolower((unsigned char)str1[i]) != tolower((unsigned char)str2[i]))
            return false;
    return true;
}

没有不必要的分配,只能循环遍历第一个不匹配的字符串。

  

编辑:更正比较功能会修复它,但我仍然想知道为什么cout << i修复它

因为程序有不确定的行为,所以任何事情都可能发生。添加随机的,不相关的代码可能会改变代码的内存分配模式,或者导致编译器稍微以不同方式对其进行优化。你会疯狂地试图解释某些未定义的行为。只是避免它。

答案 1 :(得分:1)

strcmp期望NULL终止字符串。因此,您需要为lowerStr1, lowerStr2数组保留一个字符,并将每个数组的最后一个字符设置为NULL。没有这样做,为你的程序创建了未定义的bahaviour。

但如果使用strncmp函数传递str1.size()作为第三个参数,则可以绕过所有这些问题,因为您已经检查了两个字符串是否具有相同的大小:

if (strncmp(lowerStr1, lowerStr2, str1.size()) == 0)