How to correctly increment a returned iterator in C++?
Matthew Harrington
I have an input iterator CSVIterator as defined in this SO answer.
In my program, I now want to return such an iterator in a function and use it in my main(). The iterator is returned and I can access its contents. But when trying to iterate, I encounter a segmentation fault. Iterating within the returning function works.
I have two questions:
Why do I run into a seg fault? I thought about it being a problem of scope, but shouldn't then already the access to the iterator's contents lead to a segmentation fault?
How can my problem be fixed? The idea is to switch the opened files within a bigger loop at the correct iteration and always start at the beginning of that particular file. I come from a Python background and
yielding one line of the file after the other feels natural to me, but maybe it's not recommended in C++?
Here's the code
// For the definition of CSVIterator, see
//
CSVIterator fileIter(int time)
{ std::string tstring = std::to_string(time); std::string ext = ".csv"; std::ifstream file(tstring + ext); CSVIterator iter(file); // This would work: // ++iter; return iter;
}
int main()
{ CSVIterator csvit; for (i=0; i<10000; i++) { if (i%20 == 0) { csvit = fileIter(i); } // I can access the iterator's contents // like (*csvit)[0] correctly. // However,iterating in here doesn't work. ++csvit; // seg fault here } return 0;
} 1 Answer
Yes, because file is a local variable. That means that you are iterating over something that has gone out of scope (when the function terminated), this provokes Undefined Behavior, which explains the crash.
Notice how in the answer you linked, file is declared inside main().