I have an old program in C which uses bsearch() function with strcmp() from the C library. In old gcc version4.4.7, it is running properly. But in latest Ubuntu 18.04 with gcc version7.4.0, it is giving segmentation fault. Code is given below:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <search.h>
#define MAX_CHR_IN_STR 50
#define MAX_CHR_IN_DEMO_STR 86
#define GENDER 4
#define NUMBER 4
#define PERSON 4
#define TOTAL_ENTRY 2
#define MEDIUM 50
struct mytam_gnpstr {
char mytam[MAX_CHR_IN_STR];
char mytam_lbl[MAX_CHR_IN_STR];
char gnp_str[MAX_CHR_IN_DEMO_STR];
char gen_pos[GENDER];
char num_pos[NUMBER];
char per_pos[PERSON];
};
struct mytam_gnpstr mytam_gnpstr_array[TOTAL_ENTRY] = {
"0", "0", "0[-,s,m]", "0", "s", "m",
"0_0_kara", "0_0_kara", "02[-,-,-]kara_0[-,-,-]", "0", "0", "0",
};
int main(void) {
char *rtamexample;
char TAM[MEDIUM] = "wA";
fprintf(stderr, "TAM :::::::: %s\n", TAM);
fprintf(stderr, "mytam_gnpstr_array[0].mytam :::::::: %s\n",
mytam_gnpstr_array[0].mytam);
fprintf(stderr, "TOTAL_ENTRY :::::::: %d\n", TOTAL_ENTRY);
fprintf(stderr, "sizeof(mytam_gnpstr_array[0]) :::::::: %zu\n",
sizeof(mytam_gnpstr_array[0]));
rtamexample = (char *)bsearch(TAM, mytam_gnpstr_array[0].mytam, TOTAL_ENTRY,
(sizeof(mytam_gnpstr_array[0])), strcmp);
fprintf(stderr, "bsearch :::::::: %s\n", rtamexample);
}
It is giving bsearch() output "wA" in old gcc version-4.7.7
but It is giving segmentation fault in gcc7.4.0.
Any help solving this is appreciated.
The old code is broken. It is apparently producing an answer out of thin air; the data value
wAdoes not appear anywhere in the array being searched, so any answer other than a NULL pointer is bogus. If the code shown, when compiled on the old system, produceswAas an answer, the code is IMNSHO self-evidently broken.Here is code which conforms to what's needed. It includes
<stdlib.h>since that is wherebsearch()is declared. It does not include<search.h>since that does not declare anything the code uses. Ditto for<ctype.h>. It tellsbsearch()about the array of structures it is searching, rather than passing a pointer to the start of the first member of the first element of the array. The comparator function passed in the code in the question isstrcmp(); its prototype does not match the function pointer type expected bybsearch(), so you officially get undefined behaviour there. The comparator function in this code works correctly, and expects to be given a pair of pointers to the structure type, cast toconst void *bybsearch(). The first pointer will be the key being searched for; the second will be a row from the array being searched.When compiled as shown, it produces the output:
When the entry with
wAis commented out, it produces the output:This behaviour is correct.
With the data in the question (two lines, nary a
wAanywhere in the array), you will never get anything other than NULL back from a valid invocation ofbsearch(). Expecting anything else is an exercise in futility.JFTR: compiled on macOS Mojave 10.14.6 (don't ask why it isn't Catalina) with GCC 9.2.0 and Xcode 11.3.1. I'd expect the same results on Ubuntu 18.04 LTS, or indeed any system where C99 is available. Indeed, it should work the same with C90, too.