Fenixx Reborn
Fenixx Reborn

Reputation: 15

Qsort doesn't sort array of pointers to strings

In this C program I read in words typed with my keyboard to a char pointer. The pointer is stored in an pointer array. Then I want to sort the array with qsort by the function comparison. I give it the pointer to my pointer array. It doesnt sort the array at all. I dont know if I got here a UB, or I miss memory by wrong allocation.

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

bool read_word(char ***a, int *length);
int comparison(const void *p, const void *q);


int main()
{
    int *length = malloc(sizeof(int));
    *length = 0;
    char **array = malloc(sizeof(char *));
    bool go = false;

    while(go == false)
    {
        printf("Enter word: ");

        go = read_word(&array,length);
    }

    qsort(array, *length - 1,sizeof(char *), comparison);

    printf("\n");


    for(int i = 0; i < *length; i++)
        printf("%s\n", array[i]);

    return 0;
}

bool read_word(char ***a, int *length)
{
    char ch;

    ++*length;

    char *word = malloc(20 * sizeof(char) + 1);
    char *keep_word;

    char **temp = realloc(*a,*length * sizeof(*a));

    if(!temp)
        exit(EXIT_FAILURE);

    *a = temp;

    keep_word = word;

    while((ch = getchar()) != '\n')
        *keep_word++ = ch;

    *keep_word = '\0';

    if(word == keep_word)
    {
        free(word);
        --*length;
        return true;
    }



    (*a)[*length - 1] = word;

    printf("%s", (*a)[*length -1]);
    printf("\nh\n");
    return false;
}

int comparison(const void *p, const void *q)
{
    const char *p1 = p;
    const char *q1 = q;


    return strcmp(p1,q1);
}

Upvotes: 0

Views: 599

Answers (2)

BLUEPIXY
BLUEPIXY

Reputation: 40145

change to

int length = 0;//no need malloc
char **array = NULL;//first value is NULL

qsort(array, length, sizeof(char *), comparison);//not length-1

int ch;//type of return value of getchar is int

for(int i = 0; i < 20 &&  (ch = getchar()) != '\n'; ++i)//i : guard

const char *p1 = *(const char **)p;//qsort pass pointer to object to comparison function  
const char *q1 = *(const char **)q;//if char *, char **

Upvotes: 1

user31264
user31264

Reputation: 6727

You do

keep_word = word;

and later

if(word == keep_word)

The condition in brackets is always true.

On a side note, your program is error-prone and hard to understand because you use pointers way too much. In main(), length should be int, not int*, array should be char*, not char** . In the read_word, a should be char**, not char***. Don't use pointers unless necessary!

Upvotes: 0

Related Questions