C qsort не работает как задумано, стирает элементы? - PullRequest
0 голосов
/ 01 апреля 2020

У меня небольшие проблемы с использованием qsort, доступного в C, для сортировки массива строк, которые у меня есть в моей структуре.

Мой код выглядит следующим образом:

typedef struct estrutura
{
    int sp;
    int numberOfEntries;
    int entriesSize;
    char* stack[26];
    char** list;
}*estrutura;


void createStruct (estrutura l, int numberEntries, int sizeEntries)
{
    l -> list = malloc (numberEntries * sizeof(char*));

    l -> numberOfEntries = numberEntries;
    l -> sp = 0;
    l -> entriesSize = sizeEntries;

    for (int i = 0; i < (l -> numberOfEntries); i++)
        (l -> list)[i] = malloc ((sizeEntries + 1) * sizeof(char));


}

int cmpstr(void const *a, void const *b) {
    char const *aa = (char const *)a;
    char const *bb = (char const *)b;

    return strcmp(aa, bb);
}

void addEntry (estrutura l, char* line)
{
    strcpy((l -> list)[(l -> sp)],line);
    (l -> sp)++;
}

void sortStruct (estrutura l)
{
    qsort((l -> list)[0], l -> numberOfEntries, (l -> entriesSize) * sizeof(char), cmpstr);
}

void printStruct (estrutura l)
{
    for (int i = 0; i < (l -> numberOfEntries); i++)
        printf("%s\n",(l -> list)[i]);
}

void freeStruct (estrutura l)
{
    for (int i = 0; i < (l -> numberOfEntries); i++)
        free((l -> list)[i]);

    free(l);

}

Итак, моя проблема: когда я запускаю тест в своей основной функции:

int main ()
{

    estrutura example = malloc (sizeof(struct estrutura));
    createStruct(example,2,6);

    char* name = malloc (6*sizeof(char));
    strcpy(name,"A1234");

    char* otherName = malloc(6*sizeof(char));
    strcpy(otherName, "B1234");

    addEntry(example,otherName);
    addEntry(example,name);
    printf("/////BEFORE SORTING//////\n");
    printStruct(example);
    sortStruct(example);
    printf("/////AFTER SORTING//////\n");
    printStruct(example);

freeStruct(example);

}

Вывод, который я получаю до сортировки, как и ожидалось:

"A1234"
"B1234"

Но после сортировки я получаю вывод:

"     " -> blank line
"B1234"

И это происходит для каждого теста, который я делаю. Он просто стирает первый элемент, а затем не сортирует вообще. Любая помощь будет оценена.

1 Ответ

2 голосов
/ 01 апреля 2020

Предположим, вы хотите отсортировать массив с N записями типа T:

T *array = malloc(N * sizeof(*array));

Тогда ваш вызов qsort выглядит следующим образом:

qsort(array, N, sizeof(*array), t_cmp);

Ваша функция сравнения:

int t_cmp(const void *a, const void *b)
{
    const T *aa = a;
    const T *bb = b;

    // compare *aa and *bb
}

Полученные вами указатели являются указателями на элементы массива. Они имеют тот же тип, что и дескриптор массива, array. (Если у вас есть массив фиксированного размера, как определено с помощью T a[N], эти указатели имеют тот же тип, что и массив после того, как он распался на указатель. В обоих случаях этот тип равен T *.)


В вашем случае тип T равен char *. Итак:

l->list = malloc(l->numberEntries * sizeof(*l->list));

Затем сортируйте:

qsort(l->list, l->numberOfEntries, sizeof(*l->list), cmpstr);

с помощью этой функции сравнения.

int cmpstr(void const *a, void const *b)
{
    char *const *aa = a;
    char *const *bb = b;

    return strcmp(*aa, *bb);
}

(Вместо sizeof(*l->list) вы можете использовать sizeof(char *), это будет sizeof(T), размер одного элемента массива, на языке выше).

...