Picking random items without repetition is its own special challenge. It's one of those things that's not actually hard, but some programmers have a difficult time coming up with solutions to the problem. Abraham has found these two examples in some code he maintains:

//pick 3 out of 4 int alreadyUsed = 0; while (alreadyUsed < 3) { int rand = random()%4; if(!m_AllOptions[rand]->used) { m_AllOptions[rand]->used = true; alreadyUsed++; } }

Here, they need to choose three items out of a list of four. So the solution is to keep randomly selecting items, and if their used flag isn't true, set it to true and increment. Like a lot of bad solutions to random selection, this one will probably complete in a reasonable amount of time, but might never complete.

//find a free slot int random = std::rand() % 5; while (slots[random].active) { ++random; if (random > SLOTS_MAX) { random = 0; } }

Here, there are a set of slots. I don't know exactly what they're for, but it doesn't really matter. This code attempts to round-robin its way through those slots. It starts by picking a random slot (via magic number, which I assume is equal to SLOTS_MAX, but who knows?). If that slot is active, we keep incrementing our index, wrapping back around to zero. And we just keep incrementing and searching, and we never give up.

You already know how this story ends: a different bug meant that slots weren't getting freed after user, which meant when attempting to grab a new slot, an infinite loop would trigger. Slots were also held onto for multiple seconds, so even after fixing that bug, there was a good chance that this code would enter a busy loop that hung the application while waiting for a slot to free up.

[Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!