0

i want to create std::ifstream object at runtime as i create new thread ,

ifstream& 
getMultiDataReaderStream()
{
      ifstream ifs;
        ifs.open(m_dataReaderFileName.c_str(), ios::in | ios::binary);
    return ifs;
}

void
runThread(void *lpData)
{
      ifstream& ifs1 = storeManager.getMultiDataReaderStream();
      // code for reading while EOF
      ifs1.close();
}

But , I am getting segmentation Fault is something wrong in above code....

Dipak
  • 123
  • 1
  • 1
  • 10
  • 3
    you're returning a reference to an object that gets destroyed after the function getMultiDataReaderStream is done. This reference gets used, which causes a seg fault. – thang Nov 27 '13 at 09:24
  • OK..is any other way to do this... – Dipak Nov 27 '13 at 09:25
  • there are several ways to solve this. 1. pass a reference to the object in, then call open. 2. allocate using new and return a pointer. 2a. use solution 2 with smart pointer. – thang Nov 27 '13 at 09:26

3 Answers3

1

See my comment.

There are many ways to fix this. One is this:

void getMultiDataReaderStream(ifstream& ifs)
{
    ifs.open(m_dataReaderFileName.c_str(), ios::in | ios::binary);
}

void
runThread(void *lpData)
{
      ifstream ifs1;
      getMultiDataReaderStream(ifs1);
      // code for reading while EOF
      ifs1.close();
}

Another is this: (don't use this, this works, but it's sloppy)

ifstream* getMultiDataReaderStream()
{
    ifstream* ifs = new ifstream(m_dataReaderFileName.c_str(), ios::in | ios::binary);
    return ifs;
}

void
runThread(void *lpData)
{
      ifstream* ifs1 = getMultiDataReaderStream();
      // code for reading while EOF
      ifs1->close();
      delete ifs1;
}

And then with smart ptr:

shared_ptr<ifstream> getMultiDataReaderStream()
{
    shared_ptr<ifstream> ifs = shared_ptr<ifstream>(new ifstream(m_dataReaderFileName.c_str(), ios::in | ios::binary));
    return ifs;
}

void
runThread(void *lpData)
{
      shared_ptr<ifstream> ifs1 = getMultiDataReaderStream();
      // code for reading while EOF
      ifs1->close();
}

I am sure there are other ways...

thang
  • 3,466
  • 1
  • 19
  • 31
  • Consider using `std::unique_ptr` over `std::shared_ptr` here, as there is no attested need for shared ownership. – chwarr Nov 27 '13 at 09:34
1

According to this: Is std::ofstream movable?

both ifstream and ofstream should be movable, so you should be able to simply "just return it". But, many compilers does not have their stdlibs adapted to C'11 properly. For instance, I've just tried it at http://coliru.stacked-crooked.com/ which seems to have g++ 4.8 and I still cannot move/return any fstream - compiler still insists on using nonexistent copy-constructor instead of move ctor.

This was a known issue that GCC hadn't implemented movability in the streams part. Sorry, I don't know anything more. You'll need to stick with the workarounds until c'11 support gets better.

Community
  • 1
  • 1
quetzalcoatl
  • 32,194
  • 8
  • 68
  • 107
0

You should never return a reference (or a pointer) to a local object from a function. In this case, getMultiDataReaderStream() is returning a reference to an object (ifs) that is destroyed as soon as you leave the function. So using it is invalid and leads to undefined behaviour. For instance, a segmentation fault.

Gorpik
  • 10,940
  • 4
  • 36
  • 56