C语言 使用“a>B”作为比较器时qsort意外运行

iovurdzv  于 2022-12-03  发布在  其他
关注(0)|答案(1)|浏览(153)

我遇到了一个qsort比较器函数,它错误地使用“a〉B”作为比较操作。我本以为这段代码只是随机地对数组重新排序,但它在我学校的教学服务器(Ubuntu 12.04.4 LTS)上工作。它在我自己的笔记本电脑上没有像预期的那样工作,所以我不确定是什么导致了这个bug。

#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

乌班图:

$ ./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
bq3bfh9z

bq3bfh9z1#

您违反了使用qsort的约定,因此调用了Undefined Behavior
具体来说,您的比较函数是坏的:

7.22.5.2 qsort函数

概要

#include <stdlib.h>
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));

项目名称
2 qsort函数对nmemb对象数组进行排序,base指向数组的初始元素。每个对象的大小由size指定。
3数组的内容会根据compar所指向的比较函式,以递增顺序排序,此函式会以两个指向所比较对象的参数来呼叫。如果第一个参数被视为分别小于、相等或大于第二个参数,则此函式会传回小于、相等或大于零的整数。
4如果两个元素比较结果相等,则未指定它们在结果排序数组中的顺序。
退货
5 qsort函数不返回任何值。
它应该更沿着这样:

int int_compar(const void *x, const void *y)
{
  int i_x = *(int*)x;
  int i_y = *(int*)y;
  return i_x > i_y - i_x < i_y;
}

现在,比较功能是部分功能性的而不是完全破坏的,它确实指示第一个是否大于第二个,但是不区分它们是相等的还是第二个大于
根据算法的编写方式,这可能会使算法将所有内容视为相等,对您的错误完全不作出React,或者执行一些有趣的操作。
例如,所有C++标准库排序算法都被编写为只使用小于进行比较。

相关问题