I ran into an interesting problem while working on some code, and I thought it would probably be a good idea to, well, document the problem so I can remember it in the future.
The problem was this: I have a C++ class which is the key index in a std::map class. This C++ class wraps a Mac CFUUID object and provides a unique index based on UUID. And it was mysteriously crashing.
The root of the problems I had with my class were this:
(1) I wasn’t declaring the big three entry points for a C++ class to be used as an object within a C++ container class, like a std::map class. For the handful of people out there who don’t know, these entry points are the copy constructor, the copy operator, and the destructor. In my case, I was missing the following:
class CStdUuid { public: CStdUuid(const CStdUuid &); ~CStdUuid(); CStdUuid &operator = (const CStdUuid &);
(2) In order to be used properly for comparing keys within a map, I also needed to properly declare the following compare operators:
bool operator == (const CStdUuid &) const; bool operator < (const CStdUuid &) const;
Now I’m not quite sure off the top of my head if I only need to declare these two operators to be used as a key in a std::map class, or if this just happens to be true for my particular implementation of the standard C++ template library. I’m sure a quick search with Google will yield an answer.
But why my particular implementation was crashing was simple: my implementation of the CStdUuid::operator < operator was screwed up. Because my class was returning true if the items were equal, and not when my class was less than the provided class, the std::map class became confused, and was crashing mysteriously.
Which is today’s lesson of the day: if std::map is crashing mysteriously, check your compare operators, since the tree structure inside std::map may be getting munged by an incorrectly declared compare operation.