Home > Back-end >  Getting "Exited with return code -11(SIGSEGV)" when attempting to run my code
Getting "Exited with return code -11(SIGSEGV)" when attempting to run my code

Time:09-22

#include <iostream>
#include <vector>
#include <string>
using namespace std;

vector<string> separate(string str){
   string build = "";
   vector<string> temp;
   
   for(int i = 0;i < str.size(); i  ){
      if(str[i] != ' '){
         
         build  = str[i];
         
      } else if(str[i] == ' '){
         
         temp.push_back(build);
         build = "";
      }
   }
      
      return temp;
}

int main() {
   
   int count;
   string sentence;
   vector<int> numTimes;
   
   getline(cin, sentence);
   
   vector<string> words = separate(sentence);
   
   for(int i = 0; i < words.size(); i  ){
      for(int j = 0; j < words.size(); i  ){
         if(words[i] == words[j]){
            count  ;
         }
      }
      numTimes.push_back(count);
   }
   
   for(int k = 0; k < words.size(); k  ){
      cout << words[k] << " - " << numTimes[k] << endl;
   }

   return 0;
}

The code is supposed to receive a string, separate it into the individual words, place those words into a vector and finally output the number of times the word occurs in the sentence. However when running my code, I get a message saying that the program was exited with code -11. I have looked a bit online but do not fully understand what this means or where it is occurring in my code.

CodePudding user response:

@Allan Wind is right, but to offer an alternate solution using the C 17 standard.

Iterating

Rather than use indexes, let's use a more modern for loop.

for (const char &ch : s)

Rather than:

for (size_t i = 0; i < str.size(); i  )

After all, the index is not important in this situation.

Dealing with multiple spaces

Right now, both the OP's code and Allan's will push an empty string onto the output vector whenever they encounter more than one contiguous space. We can correct that by resetting the string to empty when a space is encountered, but when a space is encountered and the string is empty, don't take any action.

We also need to check if the string is non-empty when the loop is finished. If so, we need to push that onto the output vector. We may not get a trailing space to trigger pushing that last word.

vector<string> separate(string s) {
    vector<string> output;
    string current = "";

    for (const char &ch : s) {
        if (current != "" && ch == ' ') {
            output.push_back(current);
            current = "";
        }
        else if (ch == ' ') {
            // Do nothing!
        }
        else {
            current  = ch;
        }
    }

    if (current != "") {
        output.push_back(current);
    }

    return output;
}

Putting it together so far

#include <string>
#include <vector>
#include <iostream>

using namespace std;

vector<string> separate(string s);

int main() {
    auto v = separate("hello world   foo"); 

    for (auto i : v) {
        cout << i << endl;
    }
}

vector<string> separate(string s) {
    vector<string> output;
    string current = "";

    for (const char &ch : s) {
        if (current != "" && ch == ' ') {
            output.push_back(current);
            current = "";
        }
        else if (ch == ' ') {
            // Do nothing!
        }
        else {
            current  = ch;
        }
    }

    if (current != "") {
        output.push_back(current);
    }

    return output;
}

Counting words

We can use a map to count the occurrences of words. We use a map<string, int> where each word is the key, and the val is the occurrences. As we iterate over the words, if the word already exists as a key in the map, we increment it by `. If not, we set it to 1.

int main() {
    auto v = separate("hello    world   hello world   foo");    

    map<string, int> m;

    for (auto i : v) {
        if (m[i]) {
            m[i]  = 1;
        }
        else {
            m[i] = 1;
        }
    }

    for (auto const& [key, val] : m) {
        cout << "The word \"" << key << "\" occurs " 
             << val << " times." << endl;
    }    
}

CodePudding user response:

Changed signed counter variables (i, j) to unsigned (size_t) as you compare the two. In separate(..) changed if-else-if to just if-else, and fixed the loop per @user4581301 to use the right loop variable. Also fixed last word not being added. Minor reformat to use tab/8 space for indent.

#include <iostream>
#include <vector>
#include <string>
using namespace std;

vector<string> separate(string str) {
    string build = "";
    vector<string> temp;

    for(size_t i = 0; i < str.size(); i  ) {
        if(str[i] == ' ') {
            temp.push_back(build);
            build = "";
        } else {
            build  = str[i];
        }
    }
    if(build.size()) {
        temp.push_back(build);        
    }       
 
    return temp;
}

int main() {
    int count = 0;
    string sentence;
    vector<int> numTimes;

    getline(cin, sentence);

    vector<string> words = separate(sentence);

    for(size_t i = 0; i < words.size(); i  ) {
        for(size_t j = 0; j < words.size(); j  ) {
            if(words[i] == words[j]) {
                count  ;
            }
        }
        numTimes.push_back(count);
    }

    for(size_t k = 0; k < words.size(); k  ) {
        cout << words[k] << " - " << numTimes[k] << endl;
    }

    return 0;
}

This seems to fix the segfault which answers question posed.

You haven't provided sample input and output but the counts clearly seems wrong. What do you mean with sentence? There is no notion of English sentences ending with '.' or whatever:

./a.out
a bc d
a - 1
bc - 2
d - 3
./a.out 
a a b
a - 2
a - 4
b - 5

Suggest you work on that and open new question if you need further help.

  •  Tags:  
  • c
  • Related