Sign in to follow this  
Belgium

C++ Need help with invalid object, I think.

Recommended Posts

Hello, Occassionally, my program crashes. I've narrowed it down to an overloaded operator< being used by std::sort. However, I don't think it is the operator method that is the problem. I suspect the object being compared in the method is invalid. If I add some statements to display the elements being compared using the operator< , any call to the rhs object will crash the program. Additionally, I have other code which does something very similar except with different class types and it'll crash too so I suspect I'm doing something wrong somewhere. Unfortunately, the problem takes some time to appear. The method doing the sorting appears to work without a problem hundreds of times before it'll crash. Some days it won't crash at all. However, when it does crash, it'll consistently crash at the same point when the program is run again on the same machine. Running the program on a different machine using the same data won't crash. So, I'm looking for tips to further my troubleshooting. Is there a way to detect an invalid object in C++? From what I've read there doesn't seem to be. How might an invalid object be added to a vector? I know, there isn't enough code below to determine that but are there any usual suspects for this sort of problem? I'm not using pointers in my code so I'm not pointing at something odd somewhere down the line. Below is a method which uses std::sort and eventually leads to the crash. I'm also a little worried about the use of std::unique and std::vector::erase(). I can see where if I botched something here then a subsequent use of std::sort might have issues. This is the only place where these vector of objects undergo anything other than a push_back(). However, I can't see anything wrong with what I've done.
void TicketReport::addTickets(const vector<Ticket>& vTickets, vector<Ticket>& vStoredTickets)
{
    // Copy qualifying tickets from vTickets to vStoredTickets.	

    if ( vTickets.empty() ) return;

    std::remove_copy_if(vTickets.begin(), vTickets.end(), std::back_inserter(vStoredTickets), m_fpQualifier);
    if ( vStoredTickets.empty() ) return;

    sort( vStoredTickets.begin(), vStoredTickets.end()); 
    vector<Ticket>::iterator iUnique(std::unique(vStoredTickets.begin(), vStoredTickets.end()));     
    vStoredTickets.erase(iUnique, vStoredTickets.end());
}

The operator< being used by std::sort. Below, attempting to access rhs.m_number will crash.
bool Ticket::operator< (const Ticket& rhs) const
{
    if ( m_number != rhs.m_number ) return m_number <= rhs.m_number;
    return m_name <= rhs.m_name;
} 


// The only constructor for Ticket.
Ticket::Ticket()
  : m_location( "" ),
    m_memberA( "" ),
    m_name( "" ),
    m_number( "" ),
    m_owner( "" ),
    m_state( "" )
{}

Thanks for your time.

Share this post


Link to post
Share on other sites
Quote:
Original post by Belgium
The operator< being used by std::sort. Below, attempting to access rhs.m_number will crash.
*** Source Snippet Removed ***
Why are you using <= to perform a < operation? The reason the standard library uses the less-than operator for ordering is that if !(a < b) and !(b < a) then by definition a == b. By using <= instead of <, you violate this constraint, so it is quite possible that you will screw up the sort algorithm and cause a crash.

Share this post


Link to post
Share on other sites
Quote:
Original post by swiftcoder
Why are you using <= to perform a < operation? The reason the standard library uses the less-than operator for ordering is that if !(a < b) and !(b < a) then by definition a == b. By using <= instead of <, you violate this constraint, so it is quite possible that you will screw up the sort algorithm and cause a crash.


Well, now that you mention it, it is kind of silly. I've changed that bit and reran the program and it made it past today's crash point. I'm looking forward to the next several days to see if that is indeed the problem. It would explain why another similar contructed operator had the same problem. I'll have to look up how std::sort works to see what problems this may have been causing.

Thanks!

Share this post


Link to post
Share on other sites
Whenever you are creating a STL compatible operator< (comparison function) you'll always have to take into account that a < b and b < a cannot return true at the same time (which won't be the case if you also consider one less than another if they are equal). If that condition is not met, your operator does not define a strict weak ordering: how do you sort a and b if either one is less than another?

If you make that mistake absolutely nothing in the STL will work correctly that relies on sorting/sortedness (including sorted containers like set and map).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this