Steephen
Steephen

Reputation: 15844

std::istream_iterator<double> member variable fails while incrementing

I have a program as follows:

#include <iostream>
#include <iterator>
#include <fstream>
#include <string>

class Stream{
        public:
        //default constructor
        Stream();
        //constructor
        Stream(const std::string&);
        //Returns true if more elements are available
        bool hasNext();
        //Get the next element in the stream
        double getNext();
        private:
        std::istream_iterator<double> streamHandle;
        std::istream_iterator<double> eos;
};
Stream::Stream()
{
        streamHandle = std::istream_iterator<double>(std::cin);
}
Stream::Stream(const std::string& absolutePath)
{
        std::fstream file(absolutePath);
        streamHandle = std::istream_iterator<double>(file);
}
bool Stream::hasNext()
{
        return (streamHandle != eos)? true: false;
}
double Stream::getNext()
{
        double value = *streamHandle;
        ++streamHandle;
        return value;
}
int main()
{
   Stream input("test1");
   if( input.hasNext())
       std::cout << input.getNext();

}

While executing this program,it is core dumping. I know it is happening only if it executes statement ++streamHandle;

So I implemented same functionality without using a class as follows and it works perfectly fine.

#include <iostream>
#include <iterator>
#include <fstream>
#include <string>

void readFile(const std::string& absolutePath)
{
        std::fstream file(absolutePath);
        std::istream_iterator<double> streamHandle = std::istream_iterator<double>(file);
        std::istream_iterator<double> eos;

        while( streamHandle != eos)
        {
                double val= *streamHandle;
                ++streamHandle;
                std::cout << val << "\n";
        }
}
int main()
{
   readFile("test1");
}

Could you please help me to identify what is going wrong while creating a class and iterate over std::istream_iterator<double> from the class.

Upvotes: 1

Views: 386

Answers (1)

NathanOliver
NathanOliver

Reputation: 180998

Your problem really lies in

Stream::Stream(const std::string& absolutePath)
{
        std::fstream file(absolutePath);
        streamHandle = std::istream_iterator<double>(file);
}

In the above constructor you create a local file stream and set the iterator to that. Unfortunately when the constructor exits the file stream is destroyed which close the file and leaves the iterator in an invalid state. Trying to use that iterator afterward is undefined behavior and cause the core dump.

Upvotes: 4

Related Questions