删除[]搞砸了我的程序。发生了什么?

时间:2015-12-12 06:50:09

标签: c++ arrays string pointers counting

我试图编写一个函数,检查字符串是否只有大写字母,字符串中的每个字母都有相同的数量。即AXXA是一个有效的字符串,但AXX不是。

我的checkUpper功能正常。但是我的checkLetters函数只能在程序运行时第一次运行。

当我在函数返回之前删除了delete []时,它将一直有效。但我知道它会导致内存泄漏。

我只是想问一下导致它第一次工作的原因是什么?在删除delete []后,每次运行怎么样?

任何帮助将不胜感激。非常感谢你。

#include <iostream>
#include <string>
#include <ctype.h>

using namespace std;enter code here
string input;
int NumOfLetters;

//check if everything is uppercase;
bool checkUpper(string input){
    for(int i=0;i<input.length();i++)
        if(!isupper(input[i])) return false;
    return true;
}

//check to see if there are the same number of runners for each team;
bool checkLetters(string input){
    char* Letters= new char[input.length()];//worst case, all letters are used once;
    NumOfLetters=0; //letter counter
    for(int i=0; i<input.length();i++){
        if(Letters[NumOfLetters]!=input[i]){
            Letters[NumOfLetters]=input[i]; //putting different letters in Letters
            NumOfLetters++;
        }
    }

    int *CountLetters= new int[NumOfLetters]; //used to count each letter

    for(int i=0; i<NumOfLetters;i++){
        for(int j=0;j<input.length();j++)
            if(Letters[i]==input[j])CountLetters[i]++; //counting each letter
    }

    for(int i=0; i<NumOfLetters;i++){
        if(CountLetters[i]!=CountLetters[0]){ //comparing number of each letters to the first one;
            delete[] Letters;
            delete[] CountLetters;
            return false;
        }
    }
    delete[] Letters;
    delete[] CountLetters;
    return true; 
}


int main(){
    while(true){
        cout<<"Enter a string of uppercase characters to indicate places(enter done to terminate):";
        cin>>input;
        if(input=="done") break;
        if(!checkUpper(input)){
            cout<<"Uppercase letters ONLY! try again.\n";
            continue;
        }
        if(!checkLetters(input)){
            cout<<"Each team must have the same number of runners! try again.\n";
            continue;
        }

        //to be filled;

    }
    return 0;
}

2 个答案:

答案 0 :(得分:1)

我无法从快速浏览中看到问题,但有很多评论:

  • 永远不要写裸newdelete。在非常更糟糕的情况下,请使用std::make_unique或类似内容。但是,对于此应用,std::stringstd::vector会更好。
  • 如评论中所述,您未将CountOfLetters的内容初始化为零(new不会为您执行此操作)。
  • checkLetters(初始化Letters)中的第一个循环需要是一个双循环。 (你不是在检查以前从未见过的那封信 - 只是它不是一个未初始化的价值!)
  • 您应该更喜欢将字符串作为const引用传递。

最后,checkLetters使用std::map

会更好
    bool checkLetters(const std::string& input) {
        if (input.length() == 0)
           return true;  // Just in case no characters at all.
        std::map<char,int> counts;
        for (const char c : input) {
            // No point in running over the string twice.  Do it in one go.
            if (!std::upper(c)) return false;
            // If there is an entry in the map, increment it.  If not,
            // create it (with value zero), and then increment.
            counts[c]++;
        }
        // input[0] would blow up if the string is length zero and we hadn't checked above
        const int target = counts[input[0]];
        for (const auto& keyvalue : counts)
        {
            const int value = keyvalue.second;
            if (value != target)
                return false;
        }
        return true;
   }

答案 1 :(得分:1)

编辑:我误读了问题&#34;输入中的每个字母都必须只有一个&#34;。这是我的新答案:

我浏览了你的代码并纠正了你的错误。我基本上重写了原始代码的一部分,并制作了一个简单的checkLetters函数。除非特定情况要求,否则根本不需要使用动态分配。

您所能做的就是保持map<char,int>,它存储输入中每个字母的数量。在通过输入进行交互之后,我们保留一个变量mustHaveCnt,这是每个字母必须具有的计数。现在,遍历地图中的所有字母,如果计数超过mustHaveCnt变量,则返回false。否则,答案是肯定的。

另外,我已经重写了你输入的条件。当输入&#34;完成&#34; 时,它会正确终止。

#include <iostream>
#include <string>
#include <ctype.h>
#include <map>

using namespace std;

//check if everything is uppercase;
bool checkUpper(string input){
    for(int i=0;i<input.length();i++)
        if(!isupper(input[i])) return false;
    return true;
}

//Checks if the input has the same number of runners
//use must have the header file 'map' included, e.i write "#include <map>" at the top
bool checkLetters(string input){
    map<char,int> storeCnt;
    for(int i=0;i<input.size();i++)
        storeCnt[input[i]]++; //Increment the count of each letter found
    int mustHaveCnt=storeCnt.begin()->second; //The second entry stores the count
    for(map<char,int>::iterator it= ++storeCnt.begin(); it!=storeCnt.end(); it++) //Iterate and check cnt
        if(it->second != mustHaveCnt)
            return false; //terminate here since the count does not match
    return true;
}

int main(){
    cout<<"Enter a string of uppercase characters to indicate places(enter done to terminate):\n";
    string input; //Let's avoid global declaration, unless needed
    cin>>input;
    while(input.compare("done")!=0)
    {
        int flag=1;
        if(!checkUpper(input)){
            cout<<"Uppercase letters ONLY! try again.\n";
            flag=0;
        }
        if(flag && !checkLetters(input)){
            cout<<"Each team must have the same number of runners! try again.\n";
            flag=0;
        }
        if(flag)
            cout<<"Valid String!\n";
        cin>>input;
    }
    return 0;
}