Внимательно прочитайте руководство .
Сводка замечаний, высказанных другими, а также еще пара вопросов:
Ваше использование sizeof правильно.
Вы должны передать указатель на Entry, содержащую ключ, который вы хотите найти. На самом деле ключ может быть любым, и он будет передан функции сравнения в качестве первого аргумента, и вам просто нужно привести оба аргумента к нужным типам. (Функция сравнения должна соответствовать порядку сортировки элементов.)
Неверные значения в функции сравнения. Функция сравнения получает указатель на элемент (который в вашем случае является указателем на Entry, следовательно, функция сравнения получает указатели на указатели на Entry).
Вы приводите результат к неверному типу. Опять же, функция возвращает указатель на элемент массива (указатель на указатель на Entry).
Вы не проверяете, равен ли NULL результат, если ключа там нет.
Возможно, вы могли бы отказаться от одного уровня косвенности (вам действительно нужен массив указателей вместо массива Entries?)
Вы должны взять это за хороший пример того, что люди имеют в виду, когда говорят о достоинствах безопасности типов: в вашем коде практически все типы смешаны, и вы делаете неправильные вещи с неправильными типами, но ни единой жалобы от компилятора. Это то, что вы получаете, если связываетесь с void*
, если вы точно не знаете, что делаете.
Ради забавы, имея массив указателей, требуется невероятное количество косвенных указаний, чтобы получить результат:
#include <cstdlib>
#include <string>
#include <iostream>
int compare_string(const void* a, const void* b)
{
return ((const std::string*)a)->compare(**(const std::string**)b);
}
int main()
{
std::string a("a"), b("b"), c("c");
std::string* array[3] = { &a, &b, &c };
std::string key = "b";
std::string** result = (std::string**)bsearch(&key, array, 3, sizeof(std::string*), compare_string);
if (result) std::cout << **result << '\n';
}
IMO, для реализации вашего собственного безопасного поиска типа потребуется меньше времени, чем для выяснения всего этого, проверки и отладки.