2

I'm trying to sort a array of strings in C. But it can't run. It seems I misuse qsort. Program crash in calling qsort. How can I fix my code. Should i use const char* [] instead of char[][]? Why?

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

#define N 40
#define MIN 4
#define MAX 10

int generateRandomNumber(int low, int high)/*generate random number between low and high inclusive*/
{
    return rand() % (high + 1 - low) + low;
}

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

    return strcmp(pa, pb);
}

int main()
{
    char words[N][MAX + 1];
    int i, j;
    int length;
    srand(time(NULL));

    for (i = 0; i < N; ++i)
    {
        length = generateRandomNumber(MIN, MAX);
        for (j = 0; j < length; ++j)
        {
            words[i][j] = generateRandomNumber('a', 'z');
        }
        words[i][length] = '\0';
    }

    qsort(words, N, sizeof(char*), comp);

    for (i = 0; i < N; ++i)
    {
        printf("%s\n", words[i]);
    }

    return 0;
}
5
  • Start by enabling all your compiler warnings, and by reading the manuals. Commented Nov 24, 2016 at 10:02
  • Can you give more information about the "crash" and errors? Commented Nov 24, 2016 at 10:02
  • 1) sizeof(char*) --> sizeof(*words) 2) const char* pa = *(const char**)a; const char* pb = *(const char**)b; --> const char* pa = (const char*)a; const char* pb = (const char*)b; Commented Nov 24, 2016 at 10:08
  • 3
    Why is this question tagged C++? Commented Nov 24, 2016 at 10:12
  • A pointer-to-pointer has no relation what-so-ever to a 2D array. That's why the code doesn't work. Commented Nov 24, 2016 at 10:28

4 Answers 4

1

You are not casting properly:

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

    return strcmp(pa, pb);
}

should be:

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

    return strcmp(pa, pb);
}

I do not know if there are other problems in your code, but when you cast a void* to a const char** you are sending the processor to access memory addresses that are bogus.

Sign up to request clarification or add additional context in comments.

Comments

1

You write your program as words has type char *words[N] (array of pointers to C-strings). But your type is char words[N][MAX + 1]. Its flat array, compiler can translate it to char words[N * (MAX + 1)].

So, if you really want to save type of words then:

qsort(words, N, sizeof(*words), comp);

int comp(const void* a, const void* b)
{
    return strcmp(a, b);
}

5 Comments

I think it's better: return strcmp((char *)a,(char *)b);
@SergioFormiggini You forgot the const in both casts
Why? It's redundantly in C. More over, I would write: qsort(words, N, (sizeof *words), (int (*)(void const *, void const *))strcmp);
Doing some tests I've understand that the function comp shall contain: return strcmp(*(char **)a, *(char **)b); and qsort may be: qsort(words, sizeof(words)/sizeof(char *), sizeof(char *), comp);
This would be right if words has type char *words[N].
0

In your string compare function change

const char* pa = *(const char**)a;
const char* pb = *(const char**)b;

to

 const char* pa = (const char*)a;
 const char* pb = (const char*)b;

Comments

0
const char* pa = *(const char**)a;
const char* pb = *(const char**)b;

should be:

const char* pa = (const char*)a;
const char* pb = (const char*)b;

and

qsort(words, N, sizeof(char*), comp);

should be:

qsort(words, N, sizeof(words[0]), comp);

the third parameter means the length of the array

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.