0

I'd like to sort a vector of a custom class using std::sort() and overloading the < operator. Following the answer here: Sorting a vector of custom objects, I tried the following code:

class Evnt {
    private:
        int Day, Month;
        string mydata;
    public:
      friend ifstream& operator >>(ifstream &in,Evnt &E){                                                                                                                                                                                    

        char junk;                                                                                                                                                                                                                     
        in >>junk>>E.Month>>junk>>E.Day;                                                                                                                                                                                     

         getline(in,E.mydata);                                                                                                                                                                                                             

        return in;                                                                                                                                                                                                                         
    }            

     bool operator<(const Evnt &E) const{
           if(Month < E.Month)
                   return true;
           else if(Day < E.Day)
                   return true;
           return false;
     }
};

int main(){
     ifstream inpt("inputfile.txt")
     Vector <Evnt> v;

     Evnt tmpevnt;
     while(intp>>tmpevnt)
         v.push_back(tmpevent)

      sort(v.begin(), v.end());
      return 0;
}

The last line somewhat erratically causes segmentation faults. I followed the various examples fairly closely, and so am having issues figuring out what the problem is. It seems to only occur if I read a large number (~20+) items in.

simplicio
  • 200
  • 2
  • 7
  • The first thing to do is drop this into your debugger and find out where it's crashing. – tadman Dec 10 '18 at 20:07
  • What's `E.therest` here? If that's just garbage data make a local variable for it. – tadman Dec 10 '18 at 20:09
  • 6
    Your comparison operator is not valid. Given dates `March 09` and `December 02`, your code will claim **both** dates are less than the other. – Drew Dormann Dec 10 '18 at 20:11
  • You aren't checking that individual `operator>>` operations work inside of `Evnt::operator>>`. – François Andrieux Dec 10 '18 at 20:11
  • It looks like you may have over-minimized your [mcve] and made it incomplete. Complete is just as important as minimal. Good to see you using containers and `std::sort`. Amazing how many people don't. – user4581301 Dec 10 '18 at 20:11
  • 1
    If `Month > E.Month` you are still comparing their `Day`s. – François Andrieux Dec 10 '18 at 20:13
  • To illustrate the issue, the `std::sort` will call your comparison object with two values. If one value is `March 09` and the other is `December 02`, your function says that `March 09` comes before `December 02`. However, if the sort function gives you `December 02` and `March 09`, you are now saying that `December 02` comes before `March 09`. Same data, just switched, and you are giving conflicting answers. Program (the sort) blows up on the confusion. – PaulMcKenzie Dec 10 '18 at 20:20
  • Thanks, Dormann and others pointing out the flaw in my if statement. Looks like that was the issue. – simplicio Dec 10 '18 at 20:22

1 Answers1

2

std::sort requires a comparison operation that imposes Strict Weak Ordering.

That means that if a < b returns true, b < a must not return true.

Fix your comparison operator.

 bool operator<(const Evnt &E) const{
       if(Month < E.Month)
               return true;
       else if(Month == E.Month && Day < E.Day)
               return true;
       return false;
 }

See this similar question for more information.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180