0

I'm dealing with a file with a linked list of lines with each node looking like this:

struct TextLine{
    //The actual text
    string text;
    //The line number of the document
    int line_num;
    //A pointer to the next line
    TextLine * next;
};

and I'm writing a function that adds spaces at the beginning of the lines found in the variable text, by calling functions like linelist_ptr->text.insert(0,1,'\t');

The program compiles, but when I run it I get this error:

terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::at
Aborted

Any ideas?

Omnifarious
  • 54,333
  • 19
  • 131
  • 194
vette982
  • 4,782
  • 8
  • 34
  • 41
  • 2
    You have not provided enough information. The code you've given can't fail in the manner you describe, so maybe some other code is failing that you haven't put here. – Omnifarious May 27 '10 at 03:33
  • 3
    Any reason you're not using `std::list`? (Homework?) Or even better, `std::vector`, or `std::deque`. – GManNickG May 27 '10 at 03:39
  • 1
    Can you please check if your implementation, by chance, uses `char*` as `string::iterator`? You can do `#include `, and then `std::cout << typeid(std::string::iterator).name()` - and tell the result. – Pavel Minaev May 27 '10 at 03:51

3 Answers3

1

You are using the std::string::at() somewhere in your code but you are passing it an incorrect index, hence it throws. Since you don't catch any exceptions it propagates out of main() and terminate() is called, killing the process.

The code you've shown can't fail in that way, as std::string::insert() doesn't call std::string::at(), nor are the parameters. Please add exception handling to your code and if you still can't find the bug please post a larger section of your code (or the whole file, to http://codepad.org preferably).

CMircea
  • 3,543
  • 2
  • 36
  • 58
  • 3
    This is wrong. ISO C++03 specifies that `insert()` should throw `std::out_of_range` if index is out of range (21.3.5.4[lib.string::insert]/3: "Throws: out_of_range if pos1 > size() or pos2 > str.size()."). It is perfectly legal for it to implement this requirement by calling `at()`. – Pavel Minaev May 27 '10 at 03:48
  • 1
    @Pavel, alright. However, that is not the cause as the index is 0 - which is in range of any valid std::string. – CMircea May 27 '10 at 04:16
1

I think the most likely problem from what you've described is that insert() is being invoked with an invalid position off the end of the string (i.e. > size()). You say this example is like the functions you're calling, so check the ones you may have written where you might be passing position differently than the sample code above and make sure the value is what you expect.

The terminate message is because you're not handling the out_of_range exception (via try/catch blocks), so it escapes up to the C++ language runtime, which unceremoniously shuts your program down.

Owen S.
  • 7,665
  • 1
  • 28
  • 44
0

Check that linelist_ptr has a legitimate value, i.e. that you have newed it (and it hasn't been deleted prior to you using it)

hamishmcn
  • 7,843
  • 10
  • 41
  • 46
  • Neither of these will throw std::out_of_range, at all, ever. All are undefined behavior and are likely to simply result in a segmentation fault. – CMircea May 27 '10 at 03:42
  • 2
    What I was thinking was that if the pointer was pointing at a garbage location which was then interpreted as a std::string when the call was made. – hamishmcn May 27 '10 at 03:57
  • He is dereferencing the pointer. How could that possibly result in at() being called? – CMircea May 27 '10 at 04:15
  • The point is that he may be dereferencing a pointer which is valid (from OS point of view), but points at garbage. So string length is some weird number, and when `insert` tries to compare that to start & length, it's overflowing and giving an out of range. I think that `size` would have to be `-1` for that, though, as nothing else would give such an effect in this case. – Pavel Minaev May 28 '10 at 02:03