1

i'm getting segmentation fault in my code. I've used debugger and pinpoint the error to line 14. It is not storing the input in line 13 and that's why the line 14 throws an out of bounds error. Can anyone tell me why the line 13 is not working?

using namespace std;
#include<iostream>
#include<cstring>
#include<deque>
int main()
{
    int n;
    cout<<"How many messages to read: ";
    cin>>n;
    string s;
    for(int i=1;i<=n;i++)
    {
        getline(cin,s);       //<-----LINE13
        auto it=s.begin();    //<-----LINE14
        deque<char> kingdom;
        while(s[0]!=',')
        {
            kingdom.push_back(s[0]);
            s.erase(it);
        }
        s.erase(it);
        s.erase(it);
        s.erase(it);
        while(kingdom.size()!=0)
        {
            it=s.begin();
            for(int j=0;j<s.length();j++,it++)
            {
                if(kingdom.at(0)==s.at(j))
                {
                    kingdom.pop_front();
                    s.erase(it);
                    break;
                }
            }
        }
    }
}
Shantanu
  • 331
  • 2
  • 21
  • 1
    `s.erase(it);` -- You've invalidated `it`, and you keep using it over and over again. – PaulMcKenzie Jan 10 '19 at 12:30
  • There are also some other problems in your code, like not skipping the newline after entering the value for `n`. Or any kind of error checking. What if `getline` fails? Or what if the input is not valid and what's expected? – Some programmer dude Jan 10 '19 at 12:31
  • the error occurs before that line. – Shantanu Jan 10 '19 at 12:31
  • You also call `s.erase(it)` three times. What makes you so sure that there are 3 more items to erase? (Not withstanding that the calls are incorrect, but the point is that you're assuming there are 3 more items). – PaulMcKenzie Jan 10 '19 at 12:34
  • the program question demands it – Shantanu Jan 10 '19 at 12:34
  • 1
    @ShantanuDwivedi -- One thing you learn in this business -- never write programs assuming "demands" are met. – PaulMcKenzie Jan 10 '19 at 12:35
  • Also, you wrote an outer loop, and we don't know on which iteration the error is occurring. You've already messed up the program by using an invalid iterator, and maybe it is on subsequent iterations of the `i` loop is where the program starts to fall apart. – PaulMcKenzie Jan 10 '19 at 12:38
  • the program falls on first iteration. – Shantanu Jan 10 '19 at 12:39
  • @Someprogrammerdude i thinks that is the problem with this code – Shantanu Jan 10 '19 at 12:40
  • 1
    Why do you have `using namespace std;` as the first line in your program, before any of the standard `#include`'s? Where have you seen C++ programs written in this fashion? – PaulMcKenzie Jan 10 '19 at 12:40
  • 2
    That `using namespace std;` *before* includes could do funny things, move that after them! Or preferably remove it entirely, `std::` is not so long to type. – hyde Jan 10 '19 at 12:41
  • i've tried the program with moving it but the error is still there. – Shantanu Jan 10 '19 at 12:42
  • the getline function is failing. – Shantanu Jan 10 '19 at 12:43
  • 1
    [Cannot duplicate](https://www.ideone.com/mpSrod). Please get rid of *all* of that code that comes after those lines you claim are giving an error. There is no error when that is done. – PaulMcKenzie Jan 10 '19 at 12:43
  • This is all besides the point anyway. The answer given, that you are using an invalid iterator `it` still is true. Anything else, we're guessing until you post what input you're using, or better yet, replace those input statements with hard-coded data so that we see what is going on. – PaulMcKenzie Jan 10 '19 at 12:47

2 Answers2

5

The probable root cause of your problem is this:

cin>>n;

Here you read an integer value from the user. But the user is ending the input with a Enter key, which is also added to the input buffer as a newline '\n'.

When you then call getline it will see nothing but the newline, thinking it's an empty line and therefore effectively clearing the string s, making it empty.

An empty string will have its begin iterator equal to its end iterator. And the end iterator can't be used for anything except comparing against other iterators.

It also means that any indexing (even index 0) will be out of bounds.

To solve this, you need to ignore the remainder of the line after reading n:

cin >> n;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // Skip just past the end of the line
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
2

s.erase(it) invalidates the iterator it. Subsequent usage of that operator is undefined behavior.

You should write it = s.erase(it);.

YSC
  • 38,212
  • 9
  • 96
  • 149