stdlib qsort для сортировки массива указателей на структуру

Я пытаюсь отсортировать массив указателей на структуры (определение ниже) на основе значения, хранящегося в void * структуры «ведро», которая, как я знаю, является целыми числами. Он компилирует и распечатывает мой массив сегментов и их значений без ошибок и предупреждений, но на самом деле он не сортирует массив. Я использовал утверждения, чтобы попытаться найти любое место, которое могло вызвать ошибку с qsort.

Определения структуры:

typedef struct _bucket{
   void* val;
   char *word;
}bucket;

typedef struct _root{
   bucket **list;
   int hashTableLength;
}root;

Функция сортировки, передаваемая в функцию qsort:

int sortFunc(const void *a, const void *b){
   bucket *bucketA=(bucket*)a;
   bucket *bucketB=(bucket*)b;
   int bucketAVal = *((int*)bucketA->val);
   int bucketBVal = *((int*)bucketB->val);
   assert((bucketAVal&&bucketBVal)!=0);
   return bucketAVal-bucketBVal;
}

Отсортируйте массив и распечатайте:

void sort(root* inRoot, int(*sortFunc)(const void *a, const void *b)){
   int length = inRoot->hashTableLength;
   assert(length==11); //known length of hash array
   for (int i = 0; i<length; i++)
      assert(inRoot->list[i] != NULL);
   qsort(inRoot->list, length, sizeof(bucket*), sortFunc);
   for(int i =0; i<length; i++)
      printf("%s was found %d times\n", inRoot->list[i]->word, *((int*)(inRoot->list[i]->val)));
   return;
}

person CodeMonkey    schedule 01.02.2015    source источник


Ответы (1)


Функция сравнения sortFunc() получает указатель на каждый объект. Массив inRoot->list - это массив bucket *, поэтому sortFunc() получает указатели на bucket *: bucket **.

Кроме того, при вычитании int возможны переполнения. Используйте идиоматику 2 сравнения, чтобы решить эту проблему.

int sortFunc(const void *a, const void *b) {
  bucket **bucketA = (bucket**) a;
  bucket **bucketB = (bucket**) b;
  void *vA = (*bucketA)->val;
  void *vB = (*bucketB)->val;
  int iA = *((int*) vA);
  int iB = *((int*) vB);
  return (iA > iB) - (iA < iB);
}
person chux - Reinstate Monica    schedule 01.02.2015