简体   繁体   中英

Segmentation fault in std::string::size() const ()?

I was writing a program that tell the user to input a random string, and then print out all the duplicates and the number of time each of them repeats. I was running it through gdb and this is the output:

Here is the program:

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

using namespace std;

int main()
{
  //Read a string word by word and put into a vector
  //loop through the vector:
  //  If there are two words duplicate:
  //    loop through another vector (used to store duplicate word)
  //    compare if these two words are the same as the duplicate word stored
  //      If the same: ++count[i]
  //      If not: push_back(count) ; ++count[i]

  string word;
  vector<string> sentence;
  vector<string> duplicate;
  vector<int> times;
  int count = 1;

  while (cin >> word) {
    if (word == "ctrlz") {
      break;
    }
  sentence.push_back(word);    
  }

  vector<string>::size_type i = 0;
  vector<string>::size_type j = 0;

  while (i != sentence.size()) {
    if (sentence[i] == sentence[i+1]) {
      while (j != sentence.size()) {
        if (duplicate.size() == 0) {
          duplicate.push_back(sentence[i]);
          times.push_back(count);
          ++times[0];
        }
        else { 
          if (sentence[i] != duplicate[j]) {
            duplicate.push_back(sentence[i]);
            times.push_back(count);
            ++times[j+1];          
          }
          else {
            ++times[j];
          }
        }
      ++j;
      }
    }
  ++i;  
  }

  while (i != duplicate.size()) {
    cout << duplicate[i] << ' ';
    ++i;
  }

  return 0;
}


I got this after running gdb:

(gdb) run 
Starting program: /home/phongcao/C++/6.12
phong phong phong phong phong phong 
ctrlz

Program received signal SIGSEGV, Segmentation fault.
0x001c58d9 in std::string::size() const () from /usr/lib/libstdc++.so.6 
(gdb) 


What does this output mean? How can I fix this segmentation fault?

Some bugs:

if (sentence[i] == sentence[i+1]) {

Your loop permits i to be size()-1 - So you're reading one past the end of the vector sentence.

while (i != sentence.size()) {
    while (j != sentence.size()) {
     ...
     ++j;
   }
   ++i;
}

j is never reset - next iteration of the outer loop it'll start at sentence.size() - You likely don't want that.

You should solve this with a std::map<std::string, int> :

std::map<std::string, int> words;
while (cin >> word) {
    if (word == "ctrlz") {
         break;
    }
    words[word] += 1;
}
for (std::map<std::string>::const_iterator it = words.begin(); it != words.end(); ++it) { 
     if (it->second > 1) {
         cout << it->second << " copies of " << it->first << endl;
     }
}

Rather than running it in gdb, run it in valgrind (technically "memcheck" is the name of the default tool it comes with). This will probably point right away to the source of your problems (which may or may not be exactly the place where it finally crashes).

Your problem is right here: if (sentence[i] == sentence[i+1])

On the last iteration of the loop, i == sentence.size()-1 , and i+1 == sentence.size() which is outside the bounds of the vector.

In addition, ++times[j+1]; assumes you've already push_back ed j+2 integers, but on the first time through the loop, you've only push_back ed j+1 integers.

Segmentation Fault happens when you try to access (read/write) memory that is far away from your programs variables, eg:

char s[100];
int a=100000;
s[a]=2;

So you should be looking for array indexes, and pointers and ensure they're pointing to your application memories. Also sending small arrays or unallocated pointers to functions that assume they have enough memory causes the same error (inside that function).

string.h functions assume you have made memory for them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM