【发布时间】:2014-12-24 12:33:44
【问题描述】:
我遇到了一个 qsort 比较器函数,它错误地使用“a > b”作为比较操作。我希望这段代码只是随机地重新排序阵列,但它正在我学校的教学服务器(Ubuntu 12.04.4 LTS)上运行。它没有像预期的那样在我自己的笔记本电脑上工作,所以我不确定是什么导致了这个错误。
#include <cstdio>
#include <cstdlib>
void print_arr(int* arr, size_t n) {
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("\n");
}
int int_compar(const void *x, const void *y)
{
int i_x = *((int*)x);
int i_y = *((int*)y);
return i_x > i_y;
}
int main(int argc, char *argv[])
{
int n = (1<<4);
int in[n];
for(int i = 0; i < n; i++)
in[i] = rand() % 100;
printf("Before: ");
print_arr(in, n);
qsort(in, n, sizeof(int), int_compar);
printf("After: ");
print_arr(in, n);
return 0;
}
我的笔记本电脑:
$ ./qsort_test
Before: 7 49 73 58 30 72 44 78 23 9 40 65 92 42 87 3
After: 23 7 9 3 58 44 42 40 49 30 65 72 73 78 87 92
Ubuntu:
$ ./qsort_test
Before: 83 86 77 15 93 35 86 92 49 21 62 27 90 59 63 26
After: 15 21 26 27 35 49 59 62 63 77 83 86 86 90 92 93
【问题讨论】:
-
完全靠运气“工作”;显然,该特定
qsort实现的一些细节恰好为具有该特定(损坏的)比较器的该特定输入集产生正确的结果。 -
Ubuntu
qsort()显然在fcmp()返回值为< 0或0时做同样的事情。 OP 的qsort()采用不同的路径,可能在> 0或0上也是如此。 -
glibc中qsort通常的implementation只关心比较器是否quicksort,它会关心它是否是
-
@Tavian Barnes 是的,它不太可能完全靠运气。也许有效的排序实现会不必要地交换被认为相等的值,这将适用于
i_x < i_y的情况