Josh
Josh

Reputation: 326

Unable to get qsort to work properly with struct

I'm trying to figure out how to get qsort to work properly with my struct data type. Basically I'm extracting a hashtable's contents into a basic array and then trying to sort the array. I realize that there is probably a MUCH better way of doing this whole thing, but I'm not very good with C yet and my main goal is to just get this working.

struct DataItem {
    int value;
    char* key;
};

typedef struct DataItem pair;

Here's the compare function and the function that is supposed to return the hashmap as a sorted array:

int cmp_pairs(const void* p1, const void* p2) {
    int l = ((pair*) p1)->value;
    int r = ((pair*) p2)->value;
    printf("Comparing: (%s, %d) and (%s, %d)\n", ((pair*)p1)->key,l,((pair*)p1)->key,r);
    return r - l;
}

pair** getSortedArr(hashtable *h) {

    pair **result = malloc(sizeof(pair*) * (h->itemCount)); /* Hold the number of pointers that it needs */
    int j = 0, i = 0;
    for (i = 0; i < h->size; ++i) { /* Iterate through hash array */
        if (h->hashArray[i] != NULL) {
            result[j++] = h->hashArray[i];
        }
    }
    printf("UNSORTED ARRAY\n");
    for (int i = 0; i < 5; ++i) {
        printf("%d: (%s, %d)\n", i, result[i]->key, result[i]->value);
    }

    qsort(result, j, sizeof(pair*), cmp_pairs);

    return result;
}

And here's main:

hashtable table;
hashtable *t = &table;

int main(void) {
    init(t, 50);

    char* arr[6];

    arr[0] = "Hello";
    arr[1] = "Goodbye";
    arr[2] = "Sup";
    arr[3] = "How r u";
    arr[4] = "Good";

    int intarr[6];
    intarr[0] = 1;
    intarr[1] = 4;
    intarr[2] = 2;
    intarr[3] = 8;
    intarr[4] = 9;


    // int a = 1, b = 4, c = 2, d = 8, e = 8;

    printf("Elements in array: %lu\n", sizeof(arr)/sizeof(char*) - 1);

    for (int i = 0; i < 5; ++i) {
        //printf("Hashcode for %s: %lu\n", arr[i], hashCode(arr[i])%50);
        insert(t, arr[i], intarr[i]);
    }

    display(t);

    pair **array = getSortedArr(t);

    printf("\nSORTED ARRAY\n");
    for (int i = 0; i < 5; ++i) {
        printf("%d: (%s, %d)\n", i, array[i]->key, array[i]->value);
    }

    return 0;

}

The hashtable works fine. It does it's job, and even the extraction into an array works. But qsort is acting up. I think it has to do with my compare function but it seems likes I'm implementing it correctly. Here's output from the printf statements:

UNSORTED ARRAY
0: (Goodbye, 4)
1: (Sup, 2)
2: (Hello, 1)
3: (Good, 9)
4: (How r u, 8)
Comparing: (, 41968208) and (, 41968240)
Comparing: (, 41968208) and (, 41968176)
Comparing: (    , 41968176) and (   , 41968304)
Comparing: (    , 41968208) and (   , 41968304)
Comparing: (    , 41968240) and (   , 41968304)
Comparing: (, 41968176) and (, 41968272)
Comparing: (, 41968208) and (, 41968272)
Comparing: (, 41968240) and (, 41968272)
Comparing: (, 41968304) and (, 41968272)

SORTED ARRAY
0: (Good, 9)
1: (How r u, 8)
2: (Sup, 2)
3: (Goodbye, 4)
4: (Hello, 1)
Program ended with exit code: 0

Upvotes: 1

Views: 43

Answers (1)

Ja͢ck
Ja͢ck

Reputation: 173562

Each element of your array is a pair *, but your compare function receives anonymous pointers to whatever your array elements are, so that would effectively be pair **.

So you need to dereference one more level:

(*(pair**)p1)->value

Upvotes: 2

Related Questions