Thread: Annoying Segmentation Fault

  1. #1
    Registered User
    Join Date
    Sep 2003
    Posts
    69

    Annoying Segmentation Fault

    Hello,

    I am currently working on a data processing program. I am given various lines of input and I have to parse the information to see if it's valid or not. If it is, I put it in a queue. If it's not, I ignore. When I try to print the contents in the queue, I get a segmentation fault that I can't figure out. I'm performing a loop and checking if the queue is empty or not each time. For some reason, it's printing one and then giving a segmentation fault. Here is my code (the segmentation fault section is in bold):

    Code:
    #include <iostream>
    #include <string>
    #include <queue>
    #include <cstdlib>
    
    using namespace std;
    
    class dateEvents {
      int  year, month, day, hour, minute, leadTime;
      string location, details;
    
     public:
      dateEvents(int y, int mon, int d, int hr, int min, std::string loc, string det, int lead = 0) :
      year(y), month(mon), day(d), hour(hr), minute(min), leadTime(lead), location(loc), details(det) {}
      
      bool isVaild() {
        return year == 0 ? false : true;
      }
      
      bool hasleadTime() {
        return leadTime != 0 ? true : false;
      }
      
      int getLeadTime() {
        return leadTime;
      }
      
      int convert() {
        int months[12] = {31,28,31,30,31,30,31,31,30,31,30,31}, days = 0;
     
        for (int i = 0; i < month-1; i++) //add each months # of days
           days += months[i];
           
        days += day - 1; //add the day of the month
    
        return days; // lets return the total number of days it has been
      }
      
      friend int operator == (const dateEvents& a, const dateEvents& b) {
        return a.year == b.year && a.month == b.month && a.day == b.day && a.hour == b.hour && 
            a.day == b.day && a.hour == b.hour && a.minute == b.minute ? 1 : 0;
      }
      
      friend int operator < (const dateEvents& a, const dateEvents& b) {
        if (a.year > b.year) return 0;
        else if (a.year == b.year) {
            if (a.month > b.month) return 0;
            else if (a.month == b.month) {
                if (a.day > b.day) return 0;
                else if (a.day == b.day) {
    	            if (a.hour > b.hour) return 0;
    	            else if (a.hour == b.hour) {
    	  	            if (a.minute > b.minute) return 0;
    	  	            else if (a.minute == b.minute) return 0;
    	  	            else return 1; //a.minute < b.minute
    	            }
    	            return 1; //a.hour < b.hour
                }
                else return 1; //a.day < b.day
            }
            else return 1; //a.month < b.month 
        }
        else return 1; //a.year < b.year
      }
    
      friend int operator <= (const dateEvents& a, const dateEvents& b) {
        if (a.year > b.year) return 0;
        else if (a.year == b.year) {
            if (a.month > b.month)return 0;
            else if (a.month == b.month) {
               if (a.day > b.day) return 0;
               else return 1;
            }
            else return 1; //a.month < b.month
        }
        else return 1; //a.year < b.year
      }
      
      // format date object output
      friend std::ostream& operator << (std::ostream& os, const dateEvents& d) {
    
      string months[12] = {"january","feburary","march","april","may","june"
    		       ,"july","august","september","october","november","december"};
    
      if(d.day<10)
        os<<"0";
    
      os << d.day << " " <<  months[d.month-1] << " " << d.year << "\n" << "   ";
      
      if(d.hour!=24) {
        if (d.hour < 10) os<<"0";
        os << d.hour << ":";
        if(d.minute < 10) os << "0";
        os << d.minute;
      }
      else os << "-----";
    
      os << " " << d.location << " " << d.details << "\n";
      
      }
    };
    
    dateEvents parse(string);
    
    int main() {
      string line1, line2;
      queue<dateEvents> events;
      int startDay, endDay, startDate;
    
      //grab the first two lines
      getline(cin, line1);
      getline(cin, line2);
    
      //parse them as the start and end date range
      dateEvents start(parse(line1)), end(parse(line2));
    
      //main loop, goes through each line and parses it
      while(getline(cin, line1)) {
        dateEvents newEntry(parse(line1));
    
        if(newEntry.isVaild()==true) {
          if ((newEntry <= end && start <= newEntry)) //then add to the vector
    	        events.push(newEntry);
          else if (newEntry.hasleadTime()) {
    	      startDate = newEntry.convert() - newEntry.getLeadTime();
    	      startDay = start.convert();
    	      endDay = end.convert();
    	
     	      if (startDate <= endDay && startDay <= startDate) events.push(newEntry);
          }
        }
      }
      
      while (! events.empty() ) { // remove top entry from queue
          cout << events.front() << endl;
          events.pop();
    
      }
      return 0;
    }
     
     dateEvents parse(string line) {
      int day, hours, minutes, lead, yearMonth[2] = {0}, pos=0, found;
      string location = "    ", details, tmp;
    
      //step one: parse year, month
      for(int i=0; i<2; i++)
      {
        found = line.find("/", pos);
        //test to make sure a "/" was found
        if(found == string::npos)
          return dateEvents(0,0,0,0,0,"","",0);
    
        yearMonth[i] = atoi(line.substr(pos, found).c_str());
        pos = found+1;
      }
    
      //step two: parse day
      tmp = line.substr(pos, 2), pos+=3;
      if(tmp.find("<",0)<=2 || tmp.find(" ",0)<=2 || tmp.find("(",0)<=2)
        tmp = line.substr(pos,1), pos-=1;
    
      day = atoi(tmp.c_str());
    
      //step three: figure out the time, and lead time
    
      //lets see if there is even a time attached to this entry
      tmp = line.substr(pos, 4);
    
      if(tmp.find("[",0)<4) //checks formatting
        return dateEvents(0,0,0,0,0,"","",0); 
        //throw this line out, its no good
      else if(tmp.find(":",0)<4) //yes there is a time attached to this line
      {
        //parse the hours
        found=line.find(":",pos);
        hours = atoi(line.substr(pos, found-pos).c_str()), pos=found+1;
        //parse the minutes
        found=line.find(">",pos);
        minutes = atoi(line.substr(pos, found-pos).c_str()), pos=found+1;
      }
      else //no time associated with the line
        hours=24,minutes=0; //set to max time (invaild, so I know about it)
    
      if(line.find("(",0)<25) //there is a lead time
      {
        pos = line.find("(",0);
        found = line.find(")",pos);
        lead = atoi(line.substr(pos+1, found-pos-1).c_str()), pos=found+1;
      }
      else
        lead=0;
    
      //step four: does this event have a location?
    
      if(line.find("[",pos)<30) //there exists a location for this event
      {
        found = line.find("[",pos);
        location = line.substr(found+1, 4),pos=found+5;
        pos = line.find("]",found)+1; //move pointer to the details section
      }
      pos--;
      //step five: does this event have any details?
      if(line.find(" ",pos)<50) //there must be some extra details we need to add
      {
        pos = line.find(" ",pos);
        found = line.find("\n",pos);
        details = line.substr(pos+1, 60);
      }
      return dateEvents(yearMonth[0],yearMonth[1],day,hours,minutes,location,details,lead);
    }
    Any ideas? Thanks.

  2. #2
    Registered User
    Join Date
    Oct 2004
    Posts
    120
    I don't see any reason for the seg fault when doing the pop. front doesn't remove the element, so as long as its not empty, should be fine. These kind of faults usually occur in a multi-threaded environment, but unless otherthreads are accessing the queue, thats not the case here...quite puzzling.

    On a side note, I did notice a maintenance optimization you could make to reduce your workload. In the <= operator, instead of doing all the checks there (and you didn't even check all the fields like in the < operator) you can simply do
    Code:
    return (a == b) || (a < b);
    Leverage the power of the code you've already written.

    Sorry I couldn't be of more help with your real problem.

  3. #3
    Cheesy Poofs! PJYelton's Avatar
    Join Date
    Sep 2002
    Location
    Boulder
    Posts
    1,728
    I didn't see anything specific, but I'd be willing to bet that the seg fault isn't coming from your queue but from printing out the month. You sure when you print the date object that d.month is always between 1 and 12? Because if not, I think the trouble is with the line
    Code:
     os << d.day << " " <<  months[d.month-1] << " " << d.year << "\n" << "   ";

  4. #4
    Registered User
    Join Date
    Oct 2004
    Posts
    120
    No checking is done on the month or year inputs. Simply a check for the divider. Maybe if you post the input and output as well...

  5. #5
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    I think your problem is with the following line in the parse() function:
    Code:
    return dateEvents(0,0,0,0,0,"","",0);
    If you return a dateEvents object with a month value of 0, it will give you an exception fault when you try and cout it on the line:

    Code:
    os << d.day << " " <<  months[d.month-1] << " " << d.year << "\n" << "   ";

  6. #6
    Registered User
    Join Date
    Oct 2004
    Posts
    120
    But the date object will not be in the queue if it is not valid, and a year value of 0 is not valid, so thats not it.

    The isValid function should check ALL the fields before rendering its decision, just to be safe.

  7. #7
    Registered User
    Join Date
    Sep 2003
    Posts
    69
    Thanks for all the help guys, but I figured out what was wrong. I forgot to have a return os statement in my << method.

  8. #8
    Registered User
    Join Date
    Oct 2004
    Posts
    120
    DOH! I missed that entirely.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault problem
    By odedbobi in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2008, 03:36 AM
  2. Segmentation fault
    By bennyandthejets in forum C++ Programming
    Replies: 7
    Last Post: 09-07-2005, 05:04 PM
  3. Segmentation fault
    By NoUse in forum C Programming
    Replies: 4
    Last Post: 03-26-2005, 03:29 PM
  4. Locating A Segmentation Fault
    By Stack Overflow in forum C Programming
    Replies: 12
    Last Post: 12-14-2004, 01:33 PM
  5. Segmentation fault...
    By alvifarooq in forum C++ Programming
    Replies: 14
    Last Post: 09-26-2004, 12:53 PM