qsort и bsearch массив указателей - PullRequest
2 голосов
/ 29 мая 2011

Мне нужно отсортировать массив указателей на структуру.На самом деле, мне нужно выполнить поиск среди адресов, чтобы увидеть, присутствует ли данный указатель на структуру в массиве.К сожалению, у меня нет ничего «сопоставимого» внутри этих структур, поэтому я хочу отсортировать их по адресу.Мой код такой:

item* arr[SIZE];
//something is inserted
qsort(arr, SIZE, sizeof(item*), (void*)compare_funct); 
//CUT
bsearch(curr, arr, SIZE, sizeof(item*), (void*)compare_funct);

Я пытался создать compare_funct, просто приводя указатели на int и возвращая их разницу, но, похоже, это не работаетВ частности, когда я выполняю bsearch, даже если я знаю, что элемент содержится в массиве, я всегда получаю NULL в качестве возвращаемого значения.

Ответы [ 2 ]

5 голосов
/ 29 мая 2011
int cmp_items(void const *p, void const *q)
{
    item const *a = *(item const **)p, *b = *(item const **)q;
    return b - a;
}

(Пожалуйста, не приводите compare_funct к void*. Это ничего не делает, кроме отключение проверки типов провоцирование неопределенного поведения.)

EDIT : Как указывает @R .., приведенное выше демонстрирует неопределенное поведение, если только a и b не указывают на общий массив.Для полной переносимости (но за счет непосредственного понимания), вы должны использовать

int compare_pointers(void const *p, void const *q)
{
    return memcmp(p, q, sizeof(item *));
}
0 голосов
/ 29 мая 2011

Смотри здесь.

Этот описывает его довольно хорошо, думайте об этом как об указателях на структуру вместо указателей на char.

По сути, идея состоит в том, чтобы передать struct ** casted в (void *), затем вернуть обратно в struct ** разыменование для получения struct *, а затем просто выполнить сравнение.

Получить правильный бросок с помощью qsort может быть сложно.

...