Вопрос

qsort is working here, but if each member of array v occupies sizeof(void *), why is qsort expecting sizeof(int)?

#include <stdio.h>
#include <stdlib.h>

int comp(const void *pa, const void *pb)
{
    int a = *(int *)pa;
    int b = *(int *)pb;

    if (a > b)
        return +1;
    else
    if (b > a)
        return -1;
    else
        return 0;
}

int main(void)
{
    int i, a[] = {3, 1, 2, 0, 4};
    void **v;

    v = malloc(sizeof(void *) * 5);
    for (i = 0; i < 5; i++) {
        v[i] = &a[i];
    }
    for (i = 0; i < 5; i++) {
        printf("%d\n", *(int *)v[i]);
    }
    qsort(v[0], 5, sizeof(int), comp); // why sizeof(int) if v is void **
    printf("Sorted:\n");
    for (i = 0; i < 5; i++) {
        printf("%d\n", *(int *)v[i]);
    }
    free(v);
    return 0;
}
Это было полезно?

Решение

qsort(v[0], 5, sizeof(int), comp); // why sizeof(int) if v is void **

The address of the start of the memory block to be sorted that you pass to qsort is

v[0] = &a[0]

the address of the initial element of a, so the array that you sort is a, not the block whose initial element v points to. a's elements are ints, so sizeof(int) is the correct size.

If you want to sort the array of pointers, you need to pass the address of the first element in that array, &v[0], or simply v to qsort. Then of course the size argument must be sizeof (void*):

qsort(v, 5, sizeof(void*), cmp);

but for that, you can't use the comparison function you have, you need

int cmp(const void *pa, const void *pb) {
    int a = *(int*)(*(void**)pa);
    int b = *(int*)(*(void**)pb);

    if (a > b)
        return +1;
    else
    if (b > a)
        return -1;
    else
        return 0;
}

or something similar. Since what is passed to the comparison function from qsort is the address of the things to compare, we need one indirection to get the pointers to compare, and since here we want to compare pointers by what int values they point to, we need the second indirection to get the pointed-to ints.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top