| mendozae (81) | |||
|
I have this small program just to test the library function "bsearch". I tried everything but could not figure out why I am getting the value of "noShowStudent" 0x00000000 <bad Pointer> can somebody tell me what I am doing wrong..
| |||
|
|
|||
| modoran (1245) | ||
What's this on line 15 ?
This will always return 4 on x86 and 8 on x64 arhitectures, probably not what you want. Use strcmp() directly instead of your program. | ||
|
|
||
| andywestken (1966) | |||||||||||||||
sizeof(const char*) is correct here. The fourth param of bsearch is the size of an element (which are char*s in the case of this array). The third param (here 5) is the number of elems in the array.bsearch http://www.cplusplus.com/reference/clibrary/cstdlib/bsearch/ But the Compare function doesn't make sense. The elements are char*s, as you appear to know on line 15. So why are you using int as the type for the comparison?As you have no nulls in your array, you can use something along the lines of
But if there are nulls, you will have to protect strcmp() from them. If you want to keep the treatment of the key and elem the same, cast-wise, yu have to pass the address of the key on line 15 instead of the value.
whch works with
The symmetric form can be used with qsort, too. So is quite commonly used. But beware of mixing char arrays (which store chars contiguously, in fixed size blocks) with char* arrays (where the address of the string is in the array, but the string is stored elsewhere) e.g
And does BINGO means you cannot find a student? (That they've turned up?) Note that the return value from bsearch in this case is actually a char**, not a char. So to see the returned value you need:
Andy PS As attendees is an array of const char*s, I suggest you make noShowStudent const as well. And you know that sizeof(attendees)/sizeof(attendees[0]) gives you the number of elements in the array? (so you don't have to keep the count in step with the array yourself.) PPS The int Compare is broken as it is used, even to compare ints. You either have to pass the key by address. Or cast for the first param (the key) using just (int).
or you can make it ore debug friendly by using temporary variable (these will be optimised out in the release build, so they have zero effect on performance)
BUT what this does, when used with a char* array, is compare the memory addresses of the string. And one copy of a string (e.g. the "Wonder Woman" on line 15) does not necessarily have the same address as another copy of the string (e.g. the one on line 7). So your original code (with the repaired Compare function) | |||||||||||||||
|
Last edited on
|
|||||||||||||||
| guestgulkan (2916) | ||||
I did write a reply to the original post mentioning just this thing - BUT lo and behold after checking it out I found that GCC and MSVC gave both string literals the same address - and after correcting the program it did find a match! - so I removed my post. But the C++ standards document does say that:
| ||||
|
|
||||
| andywestken (1966) | |||||
|
@guestgulkan Regarding the shared or othwerwise storage of string literals, I've added necessarily to my post and changed would to might. But if the key value had been stored in a local, or otherwise buffer, like
=> no address-based matches :-(
=> address-based matches ;-) Andy | |||||
|
Last edited on
|
|||||
| mendozae (81) | |||||
This is the main that call the functions: the main ran a series of test on the function. This is an instructors file so we as his student should not modify it.
I ran a series of test on the Compare furnished by by AndyWestken and it failed the test. This is the one I tested and failed. I don't know why it failed
So I decided to use my original function except I change the the type cast of compare from (int*) to (char*) The problem now is variable "noShowStudent " and "notRegisStudent " are closed to identical but "noShowStudent " is returning a valid address and "notRegisStudent " is always returning an address "0x00000000. WHY THAT IS THE ONE BUGGING ME. | |||||
|
|
|||||
| guestgulkan (2916) | |||||||
|
There are two may issues I see (which goes all the way back to your original post) 1. The bsearch is short for binary search - for this function to work correctly your array needs to be sorted in order. So trying to be search on an out of order array like this is pointless.
2. Given that each item in the array is a const char* and the address of each item in the array is passed as the second parameter to the bsearch function as void* - in other words the original poiter type before the void* cast was const char**. Soyour compare function should look like this:
So here is your original post - working (touch wood)
***BUT note as said earlier by AndyWestken and myself - the compiler may not put all string literals that are the same at the same address so to speak (refer to previous posts) but I found that the sode as I gave worked in MSVC and GCC. | |||||||
|
|
|||||||