Reputation: 8520
So, I have a function to compare two const void* pointers, one pointer is bigger then other if it has bigger address
int func (const void* a, const void* b)
{
return (int)((long)(a) - (long)(b));
}
I have an array of void* and array[0] is bigger than array[1]
void* array[2];
void* a = malloc(10);
void* b = malloc(10);
if (func(a, b) < 0)
{
array[0] = b;
array[1] = a;
}
else
{
array[0] = a;
array[1] = b;
}
// for example, array contains 0x15cfeb0 and 0x15cfe90
And after that I'm doing qsort and the array doesn't change!
qsort(array, 2, sizeof(void*), (*func));
// array is 0x15cfeb0 and 0x15cfe90 instead of expected 0x15cfe90 and 0x15cfeb0
What am I doing wrong?
Upvotes: 1
Views: 340
Reputation: 781068
The arguments to the comparison function are pointers to the array elements, not the array elements themselves. So you need to compare what they point to.
int func (const void* a, const void* b)
{
return (int)((long)(*(void **)a) - (long)(*(void **)b));
}
BTW, what you're doing is not really well defined. The result of converting a pointer to an integer is implementation-dependent.
There can also be overflow when converting the result of subtracting long
to int
. It would be better to just test them for less than or greater than:
uintptr_t aval = (uintptr_t)(*(void **)a);
uintptr_t bval = (uintptr_t)(*(void **)b);
if (aval == bval) {
return 0;
} else if (aval < bval) {
return -1;
} else {
return 1;
}
Upvotes: 5