Проблема, с которой вы столкнулись, заключается в том, что вам не удалось учесть один дополнительный уровень косвенности, созданный выделением блока указателей с int **arr = calloc (n, sizeof *arr);
, а затем выделением памяти для одного int
каждому указателю с arr[i] = calloc (1, sizeof *arr[i])
.
Поскольку функция сравнения int compare (const void *a, const void *b)
для qsort
ожидает указатель на элементы сортируемого массива, как a
, так и b
выше будут указатель на -поинтер от до int
в вашем случае, требующем разыменования 2-х уровней косвенности, прежде чем можно будет сравнивать целочисленные значения.
Вместо cmp_int
вам действительно нужна функция сравнения cmp_int_ptr
. Это может быть записано как:
int cmp_int_ptr (const void *a, const void *b)
{
int *ai = *(int * const *)a,
*bi = *(int * const *)b;
return (*ai > *bi) - (*ai < *bi);
}
( примечание: два уровня косвенности в приведении (int * const *)
..., которое также может быть записано как (int **)
, но для соответствуют типу параметра (const void *)
* правильное значение (int * const *)
)
Установка этого на место, добавление проверок для каждого выделения и очистка спецификации размера шрифта calloc
с использованием самого разыменованного указателя для установки type-size, вы можете сделать:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
int cmp_int_ptr (const void *a, const void *b)
{
int *ai = *(int * const *)a,
*bi = *(int * const *)b;
return (*ai > *bi) - (*ai < *bi);
}
int main (void) {
int n = 10;
int **arr = calloc (n, sizeof *arr);
if (!arr) {
perror ("calloc-arr");
return 1;
}
srand((unsigned int) time(NULL));
for (int i = 0; i < n; i++) {
if (!(arr[i] = calloc (1, sizeof *arr[i]))) {
perror ("calloc-arr[i]");
return 1;
}
*(arr[i]) = rand() % 1000;
}
for (int i = 0; i < n; i++)
printf (" %d", *(arr[i]));
putchar ('\n');
qsort (arr, 10, sizeof *arr, cmp_int_ptr);
for (int i = 0; i < n; i++) {
printf (" %d", *(arr[i]));
free (arr[i]); /* don't forget to free your int allocated */
}
putchar ('\n');
free(arr); /* now free pointers */
}
Пример использования / Вывод
$ ./bin/qsortptrtoint
654 99 402 264 680 534 155 533 397 678
99 155 264 397 402 533 534 654 678 680
Посмотрите вещи и дайте мне знать, если у вас есть вопросы.