I am making C dynamic array library, kind of. Note that I'm doing it for fun in my free time, so please do not recommend million of existing libraries.
I started implementing sorting. The array is of arbitrary element size, defined as struct:
typedef struct {
//[PRIVATE] Pointer to array data
void *array;
//[READONLY] How many elements are in array
size_t length;
//[PRIVATE] How many elements can further fit in array (allocated memory)
size_t size;
//[PRIVATE] Bytes per element
size_t elm_size;
} Array;
I originally prepared this to start with the sort function:
/** sorts the array using provided comparator method
* if metod not provided, memcmp is used
* Comparator signature
* int my_comparator ( const void * ptr1, const void * ptr2, size_t type_size );
**/
void array_sort(Array* a, int(*comparator)(const void*, const void*, size_t)) {
if(comparator == NULL)
comparator = &memcmp;
// Sorting algorithm should follow
}
However I learned about qsort
:
void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*));
Apparently, I could just pass my internal array to qsort
. I could just call that:
qsort (a->array, a->length, a->elm_size, comparator_callback);
But there's a catch - qsort
's comparator signature reads as:
int (*compar)(const void*,const void*)
While memcmp
's signature is:
int memcmp ( const void * ptr1, const void * ptr2, size_t type_size );
The element size is missing in qsort
's callback, meaning I can no longer have a generic comparator function when NULL
is passed as callback. I could manually generate comparators up to X bytes of element size, but that sounds ugly.
Can I use qsort
(or other sorting built-in) along with memcpy
? Or do I have to chose between built-in comparator and built-in sorting function?
qsort
meant to be your array'selm_size
? – Rootstockqsort
. It isqsort
that does not know their type (only the size), hence thevoid*
arguments. There is no general implementation of the comparator (which is why it is an argument) - you might need to sort on a variety ofstruct
fields, if the first choices are equal. – Romanistmemcmp
requires third argument - size.qsort
also requires size of element but doesn't pass it to comparator. That's my problem here. – Radfordqsort
. Or, you could pass an array ofstruct
toqsort
, one of whose members gives the size of another of its members (say a dynamic array). – Romanistmemcmp
even make sense? I can't think of a time I've wanted to sort an array of structs by their binary interpretation. Wouldn't it make much more sense to have the comparator passed into sort by the consumer of the function? They consumer could write the comparator with the correct knowledge of how to sort, what the element sizes are, etc. – Mortimer