5

STL sort strangeness

Posted August 2nd, 2008 in Programming by Olexandr Melnyk

Working on a simple Sudoku solver, I’ve run across a memory-related issue, which isn’t uncommon when developing C/C++ programs, but in my case it seemed somewhat weird since I haven’t been doing any dynamic memory allocations or using pointers explicitly.

After spending some time searching for the bug, I realized that the problem lied in the array shuffling code, which was similar to the code below:

#include <vector>
#include <algorithm>
 
...
 
bool random_cmp(const int a, const int b)
{
    return (rand() % 2 == 0);
}
 
...
 
vector<int> a;
sort(a.begin(), a.end(), random_cmp);

After running it a couple of times in the loop, we get a “double free or corruption” error with a couple dozen lines long backtrace and memory map (program was compiled with G++ 4.1.3). The reason of this, at the first glance, strange behaviour was the fact that comparison function must be deterministic (if a < b and b < c then a < c must be true as well). In the other case, the sort() behaviour is undefined, which it really was in our case. :)

This just teaches me once more to read the documentation carefully before doing something.

P. S. In the end, I used a simple shuffling algorithm, suggested by Sergij Tyhanskij:

void shuffle(vector<int> nums)
{
    int a, b, count = nums.size();
    for (int i = 0; i < count; i++)
    {
        a = rand() % count;
        b = rand() % count;
        swap(nums[a], nums[b]);
    }
}

As for the Sudoku solver, I have added a dedicated page for it and updated this website projects section.

Share and Enjoy:
  • Facebook
  • VKontakte
  • MySpace
  • LinkedIn
  • Twitter
  • Identi.ca
  • Tumblr
  • Digg
  • Reddit
  • del.icio.us
  • StumbleUpon
  • Google Bookmarks
  • Google Buzz
  • Live
  • Technorati
  • HackerNews
  • Slashdot
  • Hyves
  • Tuenti
  • PDF
  • stick

    Wow it seems like an incredible amount of energy went into something as absolutely braindead as shuffling the elements of an array.

    Perhaps if you had used an array instead of relying on some esoteric use of the stl you could have saved yourself and all your readers many HOURS of time.

    Live and learn. Have fun blogging instead of writing working code.

  • Rexxar

    Why you don’t you use “std::random_shuffle” defined in ?

  • http://www.omelnyk.net/ Olexandr Melnyk

    stick,

    no doubt the problem arised on a plain surface, but hopefully this post will save those many hours for someone who reads it. ;)

    Rexxar,

    didn’t know about that one — thanks for pointing out.

  • josh

    If it works for your application that’s fine, but your shuffle algorithm will have non-uniform distribution. Look up the Fisher-Yates shuffle, which is about as simple and almost certainly what std::random_shuffle uses.

  • http://www.omelnyk.net/ Olexandr Melnyk

    Although Fisher-Yates shuffle (unlike the one above) is evenly distributed in theory, its rand()-based implementation will still have a small deviation from the uniform distribution due to the modulo bias (small numbers will have higher probabilities).

blog comments powered by Disqus