diff --git a/SkipList.cpp b/SkipList.cpp index 5dee515..e70a60c 100644 --- a/SkipList.cpp +++ b/SkipList.cpp @@ -99,8 +99,16 @@ force_inline bool getCharacter(const KeyInfo &ki, int character, } bool operator<(const KeyInfo &lhs, const KeyInfo &rhs) { + // An empty key is a prefix of every key, so it sorts before any non-empty + // key. Handle empty keys up front: an empty std::span may have + // data() == nullptr, which must never be passed to memcmp. + if (lhs.key.size() == 0 || rhs.key.size() == 0) { + if (lhs.key.size() != rhs.key.size()) + return lhs.key.size() < rhs.key.size(); + return extra_ordering(lhs) < extra_ordering(rhs); + } int i = std::min(lhs.key.size(), rhs.key.size()); - int c = i > 0 ? memcmp(lhs.key.data(), rhs.key.data(), i) : 0; + int c = memcmp(lhs.key.data(), rhs.key.data(), i); if (c != 0) return c < 0;