Why does the call to bsearch() crash the presented program?

300 views Asked by At

I have an unsorted dictionary file named "dict.txt". I have managed to put the words of the file in an array and the qsort() I use also seems to be working just fine (That is, the array is sorted).

The problem arises when I call bsearch(), the program crashes and my question is:

Why is this happening?

I use gcc to compile and don't use an IDE of any sort so I don't have any debugger nor do I know how to use one (yet).

I am quite aware that the code presented here might contain several problems.

That is because I am quite new to c and my background is mainly Java (which despite the similarities seems to be a drawback, because I am so used to OO and c is obviously not OO).

Any advice would be greatly appreciated.

int strcmp_mod(const void *p1, const void *p2) {
   return strcmp(* (char * const *) p1, * (char * const *) p2);
}

int main(void) {

int size, i;
char **words;

char *pItem;
char *key = "fight";

char* buf = load_file("dict.txt"); if (buf == NULL) return 1;

size = count_words(buf);

words = (char**)malloc((size+1) * sizeof(char*));

for (i=0; i<size; i++) {
    words[i] = (char*)malloc(80 * sizeof(char));
}   

copy_words_to_lower(buf, words, size);
    words[size] = '\0';

    qsort(words, size, sizeof(char*), strcmp_mod);

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

pItem = (char *) bsearch(key, words, size, sizeof(char*), strcmp_mod);

if (pItem!=NULL)
    printf ("%s is in the array.\n", pItem);
else
    printf ("%s is not in the array.\n", key); 

return 0;
}
2

There are 2 answers

0
Amnon On BEST ANSWER

Try giving bsearch the address of key.

3
Steve Jessop On

Why is this happening?

You're passing a char* as the key parameter to bsearch, but your comparator expects the result of casting a char** to void*.

Once you've fixed that, the next problem is that the return value from bsearch is a pointer to the matching item in the array. So again a char** not a char*.

Any advice would be greatly appreciated.

Either get a debugger, or else get ready to add lots of logging to your code.

Also the construction of your words array is slightly off. As it is it gets the job done, but it might be an idea to allocate the buffer for each word as you go, rather than all the same size at the start. Who knows if somebody will send you a file with a word in it more than 80 chars long? You terminate the list of words with a nul character, '\0', when you probably mean to terminate it with a null pointer, NULL. '\0' actually works, because it's another way of saying 0, and 0 converts to a null pointer. But it's not what you mean. And the array doesn't need to be null-terminated at all right now, because every time you use it after that you specify its length, size.