Search code examples
c++segmentation-faultifstream

segmentation fault with ifstream pointer in class


I'm opening an ifstream inside a class (class File in code below), then using a separate class to read a record from the ifstream (class Record below). However, after the initial object is created, the code segfaults when I access the ifstream from the subclass.

Code:

#include <fstream>
#include <iostream>
#include <vector>
#include <string>

class Record {
  std::ifstream * stream;
public:
  Record(std::ifstream * infile) : stream(infile) {};
  int position() { return (int) stream->tellg(); };  // function errors when run from main()
};

class File {
  std::ifstream stream;
public:
  File(std::string path) {
    std::ifstream stream(path, std::ios::binary);
    records.push_back(Record(&stream));
    // I can call record.position() without error after creation
    std::cout << "position after creation: " << records[0].position() << std::endl;
  };
  std::vector<Record> records;
};

int main() {
  File file("/home/jmcrae/test.txt");
  file.records[0].position(); // calling this segfaults
}

// gcc -lstdc++ -std=c++11 test.cpp

I'm pretty sure the ifstream isn't being initialized within the Record class, but I can't see why not. Creating a Record within a File object, and then calling position() works correctly, but only if accessed within the File object. Any help here would be appreciated.


Solution

  • You have two different variables named stream: the member attribute of File, and a local variable to File's constructor. Within File's constructor, you initialize the local variable stream, and then pass a pointer to this object to the constructor for Record. Once File's constructor exits, this std::ifstream goes out of scope. You code then segfaults when Record attempts to resolve its pointer to a no longer existent std::ifstream.

    To fix this, replace the line

    std::ifstream stream(path, std::ios::binary);
    

    with

    stream = std::ifstream(path, std::ios::binary);