C の文字列の配列に対して c の組み込み bsearch を使用しようとすると、混乱する動作が発生します。コードは次のとおりです。組み込みの strcmp を使用して文字列の配列を検索できることは知っていますが、なぜ機能しないのかわからなかったので、デバッグ目的で myStrCmp を含めました。
const char *stateNames[] = {"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "Washington DC", "West Virginia", "Wisconsin", "Wyoming"};
int myStrCmp(const void *s1, const void *s2) {
printf("myStrCmp: s1(%p): %s, s2(%p): %s\n", s1, (char *)s1, s2, (char *)s2);
return strcmp(s1, s2);
}
int determineState(char *state) {
printf("state: %s\n", state);
for(int i = 0; i < 51; i++)
printf("stateNames[%i](%p): %s\n", i, &(stateNames[i]), stateNames[i]);
char *found = (char *) bsearch(state, stateNames, 51, sizeof(char *), myStrCmp );
if(found == NULL)
return -1;
return 0;
}
Alabama を検索するためにこの関数が呼び出されたときの出力の一部を次に示します。
stateNames[0](0x618440): Alabama
stateNames[1](0x618448): Alaska
stateNames[2](0x618450): Arizona
...
stateNames[24](0x618500): Missouri
stateNames[25](0x618508): Montana
stateNames[26](0x618510): Nebraska
stateNames[27](0x618518): Nevada
stateNames[28](0x618520): New Hampshire
stateNames[29](0x618528): New Jersey
stateNames[30](0x618530): New Mexico
stateNames[31](0x618538): New York
stateNames[32](0x618540): North Carolina
stateNames[33](0x618548): North Dakota
stateNames[34](0x618550): Ohio
stateNames[35](0x618558): Oklahoma
stateNames[36](0x618560): Oregon
stateNames[37](0x618568): Pennsylvania
stateNames[38](0x618570): Rhode Island
stateNames[39](0x618578): South Carolina
stateNames[40](0x618580): South Dakota
stateNames[41](0x618588): Tennessee
stateNames[42](0x618590): Texas
stateNames[43](0x618598): Utah
stateNames[44](0x6185a0): Vermont
stateNames[45](0x6185a8): Virginia
stateNames[46](0x6185b0): Washington
stateNames[47](0x6185b8): Washington DC
stateNames[48](0x6185c0): West Virginia
stateNames[49](0x6185c8): Wisconsin
stateNames[50](0x6185d0): Wyoming
myStrCmp: s1(0x415430): Alabama, s2(0x618508):
UA
myStrCmp: s1(0x415430): Alabama, s2(0x618570): A
myStrCmp: s1(0x415430): Alabama, s2(0x618540): PUA
myStrCmp: s1(0x415430): Alabama, s2(0x618528): 1UA
myStrCmp: s1(0x415430): Alabama, s2(0x618538): GUA
myStrCmp: s1(0x415430): Alabama, s2(0x618530): <UA
ご覧のとおり、検索の過程で bsearch が訪れた場所には有効な文字列が含まれているはずですが (bsearch を呼び出す前に確認したように)、その場所で char * を出力しようとすると、出力はガベージになります。誰かが私の間違いを見ることができますか? ちなみに、最後のパラメーターを次のように設定して bsearch を呼び出すと、同じ悪い動作が発生します (ただし、明らかにそれを厳密に追跡することはできません)。
(int(*)(const void*, const void*))strcmp
ありがとう!