Search code examples
cbsearch

Odd point issue by null pointer


I am doing a code practice using C language.

As below codes,

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _CRT_SECURE_NO_WARNINGS

int ACDSort(const void *p1, const void *p2);
int Compare(const void *pKey, const void *pValue);
int main(void)
{
    char * strAry[4] = {"Hardware","Cookie","Boy","Power"};
    char * destStr = "Cookie";

    //qsort((void*)strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), ACDSort);

    char **ptrAdr = (char**)bsearch((void*)destStr, strAry, sizeof(strAry) / sizeof(char*), sizeof(char*), Compare);

    printf("%s\n", *ptrAdr);
}

int Compare(const void *pKey, const void *pValue) {
    char *key = ((char*)pKey);
    char *value = *((char**)pValue);
    return strcmp(key, value);
}

int ACDSort(const void *p1, const void *p2) {

    char * n1 = *((char**)p1);
    char * n2 = *((char**)p2);
    int ret;

    if (strlen(n1) > strlen(n2))
        ret = 1;
    else if (strlen(n1) < strlen(n2))
        ret = -1;
    else
        ret = 0;
    return ret;
}

I called bsearch to find the string of cookie. The problem is that the error occurred when I erased the // in order to sort the array based on the string length. I don't know why the error was executed because I think that qsort couldn't be able to significant affect to my codes.

Could you tell me the reason why the error occurred returning null pointer when erasing the //?

Ps. I used qsort and bsearch to get familiar with pointer variables.


Solution

  • bsearch uses binary search, that's why. Binary search requires the data to be sorted. Sort the string array in alphabetic order and it will work.

    As a side note, you need to get rid of all those superfluous casts, all they do is to hide potential bugs.

    Working program after fixes and clean-up:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int compare (const void* p1, const void* p2);
    
    int main (void)
    {
        const char* strAry[4] = {"Boy", "Cookie", "Hardware", "Power"};
        const char* key = "Cookie";
    
        char** ptrAdr = bsearch(key, 
                                strAry, 
                                sizeof(strAry)/sizeof(*strAry), 
                                sizeof(*strAry), 
                                compare);
    
        printf("%s\n", *ptrAdr);
    }
    
    int compare (const void* p1, const void* p2) 
    {
      const char* s1 = p1;
      const char* s2 = *(const char* const*)p2;
    
      return strcmp(s1, s2);
    }
    

    p2 will end up a const void pointer to a const char*, which is why we get that weird-looking cast when striving for const-correctness.