Search code examples
arrayscstructgdbqsort

Sorting an array of structs with qsort


I'm writing a program that sorts a "bigram array." Basically, I have an array that contains BigramObjects. Each object contains a "count" and "bigram." I want to sort my bigram array in order of "count." Below is the code I've attempted to use to solve this.

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

#include "bigramArray.h"

typedef struct bigramObject *BigramObject; 

struct bigramObject {
    char *bigram;
    int count;
};

struct bigramArray {
    BigramObject *data;
    int size;
};

#define NUMBER_OF_CHARACTERS (256)

BigramArray bigramArrayCreate(void) {
    BigramArray b = malloc(sizeof(struct bigramArray));
    assert(b);

    b->size = NUMBER_OF_CHARACTERS * NUMBER_OF_CHARACTERS;
    b->data = malloc(sizeof(struct bigramObject) * NUMBER_OF_CHARACTERS * NUMBER_OF_CHARACTERS);
    assert(b->data);
    
    for(int i = 0; i < NUMBER_OF_CHARACTERS; i++) {
        for(int j = 0; j < NUMBER_OF_CHARACTERS; j++) {
            BigramObject obj = malloc(sizeof(struct bigramObject));
            assert(obj);
            
            //Store the bigram for this cell
            obj->bigram = malloc(sizeof(char) * 2);
            assert(obj->bigram);

            obj->bigram[0] = i;
            obj->bigram[1] = j;
            obj->count = 0;
            
            b->data[i * NUMBER_OF_CHARACTERS + j] = obj;
            
        }
    }
    return b;
}

void bigramArrayDestroy(BigramArray b) {
    for(int i = 0; i < NUMBER_OF_CHARACTERS; i++) {
        for(int j = 0; j < NUMBER_OF_CHARACTERS; j++) {
            free(b->data[i * NUMBER_OF_CHARACTERS + j]->bigram);
            free(b->data[i * NUMBER_OF_CHARACTERS + j]);
        }
    }
    
    free(b->data);
    free(b);
}

int compare(const void *a, const void *b) {

    const BigramObject objA = (BigramObject) a;
    const BigramObject objB = (BigramObject) b;
    
    return objA->count - objB->count;
}

void sortBigramArray(BigramArray b) {
    // UP TO HERE IS GOOD
    qsort(b->data, b->size, sizeof(BigramObject), compare);
}

However, when I test the sort, the program doesn't sort anything at all. I've ran gdb on a completely vanilla bigram array (basically all the counts are 0), and I noticed that objA and objB both do not have counts of 0 (they are closer to numbers like 4215872 and have differences of multiples of two after I stepped through a few). In the sortBigramArray function all the counts were still 0. Could someone explain to me why this change is occurring?


Solution

  • The arguments in the compare function are pointers to the element. So you need to add correct typecast and then dereference the pointers:

    const BigramObject objA = *(BigramObject *)a
    const BigramObject objB = *(BigramObject *)b;