ifstream - C++ getline segmentation fault, std::vector<custom class> -


i've been looking @ while in debugger while googling around, think i've stumbled upon c++ behavior i'm not familiar with. i'm going give quick outline on i'm doing , what/where problem is. i'll put code block below.

the rough outline of what's happening is:

  1. created custom class (logreader) handle single log file.
  2. logreader contains pointer ifstream (ifstream *log_file)
  3. the ifstream used getline() in constructor, works fine.
  4. the logreader placed in vector.
    • the code below main.cpp using logreader directly (without vector). segfault occurs in both cases.
  5. logreader.advance() called. getline() used in function. segfault occurs here (commented in logreader.cpp).

thanks on c++ behaviors i'm missing might causing this!

edit: not placing logreader vector removes segfault (failing elsewhere now, not problem). change commenting following line out in main.cpp

readers.push_back(&label_reader); 

i guess question why using std::vector causing problem.


logreader.h

#ifndef logreader #define logreader  using namespace std;  class logreader {      private:          logreader(){} // private default constructor       public:          ifstream *log_file; // file log read          vector<int> val_locations; // offsets in line values          string next_line; // next line file           int current_time; // time recent reading          string current_line;          int next_time; // next time in file          vector<string> current_vals; // current vals           logreader(string log_loc, vector<int> offsets); // given file start on           bool advance(int new_time); // advance log reader, return true if advanced          bool has_more(); // there more in log  };   #endif 

logreader.cpp

// c++ imports #include <boost/algorithm/string.hpp> #include <fstream> #include <iostream> #include <string> #include <vector>  // imports #include "logreader.h" #include "functions.h"  using namespace std;  logreader::logreader(string log_loc, vector<int> offsets){     // make file reader     ifstream lf(log_loc);     log_file = &lf;     // pull out first line     getline(*log_file, current_line);     cout << current_line << endl;      // set of current values     val_locations = offsets;     for(int = 0; < val_locations.size(); i++) {         current_vals.push_back(get_line_part(current_line,                      val_locations.at(i)));     }     // current time     current_time = stoi(get_line_part(current_line, 0));      // pull down next line     getline(*log_file, next_line);     cout << next_line << endl;     // next time     next_time = stoi(get_line_part(next_line, 0)); }  bool logreader::advance(int new_time){     if(new_time < next_time)         return false; // nothing do, current still      cout << "can check time" << endl;      // update time , values     current_time = next_time;     current_line = next_line;     current_vals.clear();      cout << "can housekeeping" << endl;      for(int = 0; < val_locations.size(); i++) {         current_vals.push_back(get_line_part(next_line,                      val_locations.at(i)));     }      cout << "can push in new values" << endl;      // move line     next_line.clear();     if(!getline(*log_file, next_line)) {  // **segfault**         // no more lines         cout << "no more lines" << endl;         next_line.clear();         next_time = -1;         return true;     }     cout << "got line" << endl;     // update time     next_time = stoi(get_line_part(next_line, 0));     return true; }  bool logreader::has_more(){     return next_time != -1; } 

main.cpp

// c imports #include <time.h>  // c++ imports #include <algorithm> #include <boost/algorithm/string.hpp> #include <boost/date_time.hpp> #include <boost/date_time/posix_time/posix_time.hpp> #include <boost/filesystem.hpp> #include <fstream> #include <iostream> #include <string> #include <sstream> #include <vector>  // imports #include "logreader.h" #include "functions.h"  // custom shorter namespaces namespace bfs = boost::filesystem;  // used namespaces using namespace std;  void update_line(int *current_time, string *current_line,          ifstream *current_file){     if(!getline(*current_file, *current_line)){         *current_time = -1;         current_line->clear();         return;     }      try {         *current_time = stoi(get_line_part(*current_line, 0));     } catch (int e) {         cout << "update line, bad stoi on time" << endl;         cout << *current_line << endl;         throw e;     } }  void update_vals(vector<float*> vals, string line) {     for(int = 0; < vals.size(); i++) {         // offset fact first 2 time , sensor         try {             *(vals.at(i)) = stof(get_line_part(line, 2 + i));         } catch (int e) {             cout << "update_vals, bad stof " << << endl;             cout << line << endl;             throw e;         }     } }  string get_correct_file(string name, vector<string> options) {     for(int =0; < options.size(); i++) {         string option = options.at(i);         if(boost::algorithm::contains(option, name)){             return option;         }     }      return string(""); }  int main(int argc, char* argv[]) {     // open base dir     bfs::path base_dir("log/");     if(!bfs::exists(base_dir) && !bfs::is_directory(base_dir)){         cout << "bad base directory" << endl;         return 1;     }      // create vector of possible traces     vector<string> traces;     for(bfs::directory_iterator iter(base_dir);             iter != bfs::directory_iterator(); iter++) {         stringstream trace_path;         trace_path << iter->path().string();         traces.push_back(trace_path.str());     }      int trace_index = user_choose_option(traces);      // load directory     bfs::path trace_dir(traces.at(trace_index));     if(!bfs::exists(base_dir) && !bfs::is_directory(base_dir)){         cout << "selected bad trace directory" << endl;         return 1;     }      // image directory     cout << "loading image directory" << endl;     string img_path_string = trace_dir.string();     stringstream img_path_stream;     img_path_stream << img_path_string << "/img/";     bfs::path img_dir(img_path_stream.str());     if(!bfs::exists(img_dir) && !bfs::is_directory(img_dir)){         cout << "no image directory" << endl;         return 1;     }      // image list, ends in sorted order naming conventions     cout << "getting image paths" << endl;     vector<string> image_paths;     for(bfs::directory_iterator iter(img_dir);             iter != bfs::directory_iterator(); iter++) {         stringstream image_path;         image_path << iter->path().string();         image_paths.push_back(image_path.str());     }      // data traces     cout << "loading data traces" << endl;     vector<string> log_paths;     vector<string> label_paths;     string trace_path_string = trace_dir.string();     for(bfs::directory_iterator iter(trace_path_string);             iter != bfs::directory_iterator(); iter++) {         string cur_file = iter->path().string();         cout << cur_file << endl;         if(boost::algorithm::contains(cur_file, "label-")) {             label_paths.push_back(cur_file);         } else if(boost::algorithm::contains(cur_file, "log-")) {             log_paths.push_back(cur_file);         }     }     cout << endl;      // temp reading in line parts     // istringstream temp;      cout << "getting log readers" << endl;     // choose label file use, first line     int label_index = user_choose_option(label_paths);     vector<int> label_offsets;     label_offsets.push_back(1);     logreader label_reader(label_paths.at(label_index), label_offsets);     /*     ifstream label_file(label_paths.at(label_index));     string label_line;     getline(label_file, label_line);     int label_time;     temp.clear();     temp.str(get_line_part(label_line, 0));     temp >> label_time;     string label_current = get_line_part(label_line, 1);     */      /*     // accel     string accel_path = get_correct_file("accel", log_paths);     vector<int> accel_offsets;     accel_offsets.push_back(2);     accel_offsets.push_back(3);     accel_offsets.push_back(4);     logreader accel_reader(accel_path, accel_offsets);     */      vector<logreader*> readers;     vector<bool> updated;     readers.push_back(&label_reader);     updated.push_back(true); //    readers.push_back(&accel_reader); //    updated.push_back(true);      int l_time = current_time_min(readers);     while(label_reader.has_more() ){ // || accel_reader.has_more()) {         // figure out time advance         int n_time;         cout << label_reader.has_more() << endl;         if(same_current_time(readers)) {             n_time = next_time_min(readers);         } else {             n_time = current_time_nextmin(readers);         }         cout << n_time << endl;          label_reader.advance(n_time);         cout << label_reader.current_line << endl;         /*         // advance readers         for(int = 0; < readers.size(); i++) {             cout << "loop " << << endl;             // keep track of values updated             readers.at(i);             cout << "can vector" << endl;             bool advanced = readers.at(i)->advance(n_time);             cout << advanced << endl;             if(advanced) {                 updated.at(i) = true;             } else {                 updated.at(i) = false;             }         }          // sanity check printing         for(int = 0; < readers.size(); i++) {             cout << readers.at(i)->current_line << endl;         }         */          // deal statistics here      }      /*     ifstream accel_file(accel_path);     string accel_line;     getline(accel_file, accel_line);     int accel_time;     temp.clear();     temp.str(get_line_part(accel_line, 0));     temp >> accel_time;     float accel_current_x = stof(get_line_part(accel_line, 2));     float accel_current_y = stof(get_line_part(accel_line, 3));     float accel_current_z = stof(get_line_part(accel_line, 4));     vector<float*> accel_vals;     accel_vals.push_back(&accel_current_x);     accel_vals.push_back(&accel_current_y);     accel_vals.push_back(&accel_current_z);      // sprox     string sprox_path = get_correct_file("sprox", log_paths);     ifstream sprox_file(sprox_path);     string sprox_line;     getline(sprox_file, sprox_line);     int sprox_time;     temp.clear();     temp.str(get_line_part(sprox_line, 0));     temp >> sprox_time;     float sprox_current = stof(get_line_part(sprox_line, 2));     vector<float*> sprox_vals;     sprox_vals.push_back(&sprox_current);      // lprox     string lprox_path = get_correct_file("lprox", log_paths);     ifstream lprox_file(lprox_path);     string lprox_line;     getline(lprox_file, lprox_line);     int lprox_time;     temp.clear();     temp.str(get_line_part(lprox_line, 0));     temp >> lprox_time;     float lprox_current = stof(get_line_part(lprox_line, 2));     vector<float*> lprox_vals;     lprox_vals.push_back(&lprox_current);      // light     string light_path = get_correct_file("light", log_paths);     ifstream light_file(light_path);     string light_line;     getline(light_file, light_line);     int light_time;     temp.clear();     temp.str(get_line_part(light_line, 0));     temp >> light_time;     float light_current = stof(get_line_part(light_line, 2));     vector<float*> light_vals;     light_vals.push_back(&light_current);     */  //    int time_current = min(label_time, min(sprox_time,  //                min(lprox_time, min(accel_time,  //                light_time))));      /*     // variables processing here     int total_time = 0;     map<string, int> label_counts;      while(label_time != -1 || accel_time != -1 || sprox_time != -1             || lprox_time != -1 || light_time != -1) {         time_current++;         if(label_time != -1 && time_current > label_time) {             update_line(&label_time, &label_line, &label_file);             if(label_line.size() > 0) // if last label, don't overwrite                 label_current = get_line_part(label_line, 1);         }         if(accel_time != -1 && time_current > accel_time) {             update_line(&accel_time, &accel_line, &accel_file);             if(accel_line.size() > 0) // if last line, don't overwrite                 update_vals(accel_vals, accel_line);         }         if(sprox_time != -1 && time_current > sprox_time) {             update_line(&sprox_time, &sprox_line, &sprox_file);             if(sprox_line.size() > 0) // if last line, don't overwrite                 update_vals(sprox_vals, sprox_line);         }         if(lprox_time != -1 && time_current > lprox_time) {             update_line(&lprox_time, &lprox_line, &lprox_file);             if(lprox_line.size() > 0) // if last line, don't overwrite                 update_vals(lprox_vals, lprox_line);         }         if(light_time != -1 && time_current > light_time) {             update_line(&light_time, &light_line, &light_file);             if(light_line.size() > 0) // if last line, don't overwrite                 update_vals(light_vals, light_line);         }          // processing happens here         total_time++;         if(label_counts.count(label_current) == 0)             // not in map             label_counts[label_current] = 0;         label_counts[label_current]++;     }      // post processing happens here     cout << "labels counts:" << endl;     for(map<string, int>::iterator = label_counts.begin();              != label_counts.end(); it++) {         cout << it->first << " -> " << it->second << " -> ";         cout << 1.0 * it->second / total_time << endl;     }     */ } 

your program exhibits undefined behavior since using pointer object has been deleted.

ifstream lf(log_loc); log_file = &lf; 

if gets deleted when constructor returns , still holding on pointer object.

change log_file object instead of pointer.


Comments

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -