Сообщить о дубликатах в массиве структур с помощью qsort?

Что я пытаюсь выполнить:

Я делаю 3000 запросов и фиксирую 8 байт этого запроса. Вставляю ответ:

struct negs
{
    int neg_num;
    char neg_key[9];
};

где neg_num == i (номер запроса) и memcpy(nego[neg_count].neg_key, recv_data+73,8);

Мне нужно найти дубликаты neg_keys в структуре nego. Я пытаюсь использовать qsort для этого... это моя функция сравнения:

int compare( const void* a, const void* b ){
    negs *ia = *(negs **)a;
    negs *ib = *(negs **)b;
    return memcmp(ia->neg_key, ia->neg_key, 8);
}

и мой вызов qsort:

    printf("Sizeof = %d"), sizeof(*nego);
    qsort(nego,4,sizeof(*nego),compare);
    printf("Sizeof2 = %d"), sizeof(*nego);

Я планировал просто посмотреть, есть ли разница в sizeof после вызова, но это всегда возвращается:

Sizeof = 159218900
Sizeof2 = 4

Я подхожу к этому неправильно? какие-либо предложения?


Вот соответствующий код, который вызывает сегментацию:

char current_key[9];
int key_index = 0;
int dupe_count = 0;

typedef struct {
    int neg_num;
    char neg_key[9];
} negs;

struct negs
{
    int neg_num;
    char neg_key[9];
};



...

int compare( const void* a, const void* b ){
    negs *ia = *(negs **)a;
    negs *ib = *(negs **)b;
    return memcmp(ia->neg_key, ia->neg_key, 8);
}


...


main(int argc, char **argv) {
    char send_smbNego[] = {
0x00,0x00,0x00,0x54,0xFf,0x53
        };

    int neg_count = 0;
    int neg_max = 3000;

    struct negs *nego;



    nego = malloc(neg_max * sizeof(struct negs));
    for (neg_count = 0 ; neg_count < neg_max ; neg_count++){
                if ((sock = open_socket(target, TCP, 445))>=0) {
                        send(sock, send_smbNego, sizeof(send_smbNego), 0);
                        len = recv(sock, recv_data, OUTBUF_LEN, 0);
            if (len > 81) { // This should be changed to look for SMB header: ff534d42 followed by 72 which is SMB Command Negotiate Protocol, followed by 00000000 which indicates success.  The encryption key or challenge token is at offset 73 and is 8 bytes long;
                nego[neg_count].neg_num = neg_count;
                memcpy(current_key, recv_data+73,8);                   
                memcpy(nego[neg_count].neg_key, recv_data+73,8);
                //print_hex("Key 1 = ",nego[neg_count].neg_key,8);
                //printf("\n");
            }

    close(sock);

    }
    print_hex("Key number 0",nego[0].neg_key,8);
    printf("Sizeof = %d"), sizeof(*nego);
    qsort(nego,4,sizeof(*nego),compare);
    printf("Sizeof2 = %d"), sizeof(*nego);



}
}

person wish_it_was_python    schedule 05.03.2010    source источник


Ответы (2)


Для начала это выглядит так: -

return memcmp(ia->neg_key, ia->neg_key, 8);

должно быть:-

return memcmp(ia->neg_key, ib->neg_key, 8);

Вы также сообщаете qsort, что в массиве есть 4 элемента для сортировки, тогда как у вас есть 3000: -

qsort(nego,4,sizeof(*nego),compare);

Но больше всего qsort не удалит дубликаты в массиве, поэтому даже если sizeof() сделает то, что вы хотите, массивы все равно будут одинакового размера как до, так и после сортировки.

Однако для того, что вы хотите выполнить, сортировка является хорошим первым шагом, но затем вам придется пройтись по массиву после сортировки и искать дубликаты, memcmp'ing каждый элемент к следующему.

person Andrew O'Reilly    schedule 05.03.2010

Вы поместили sizeof за скобки printf. Должен быть:

printf("Sizeof = %d\n", sizeof(*nego));

Однако я не понимаю, чего вы пытаетесь достичь, поскольку sizeof никогда не изменится - он вычисляется во время компиляции в соответствии с типом nego.


Что касается вашей функции сравнения, если nego является массивом struct negs (а не массивом указателей), вам нужно привести параметры к negs *, а не к negs**. Кроме того, в настоящее время вы сравниваете первый ключ с самим собой в вызове memcmp.


Редактировать: как я уже упоминал, ваш segfaulting вызван неправильным использованием двойных указателей. Ваша функция сравнения должна выглядеть так:

int compare( const void* a, const void* b ){
    negs *ia = (negs *)a;
    negs *ib = (negs *)b;
    return memcmp(ia->neg_key, ib->neg_key, 8);
}
person interjay    schedule 05.03.2010
comment
Большое спасибо вам обоим за помощь... Теперь я понимаю, что qsort просто отсортирует мой массив структур и что мне придется написать цикл, чтобы проверить, если memcmp(nego[i].key == nego[i+ 1], 8) ... но я еще не совсем там. К сожалению, после внесения предложенных изменений я ошибаюсь.. в частности, когда я исправил ошибку в возврате: return memcmp(ia-›neg_key, ib-›neg_key, 8); какие-нибудь мысли о том, почему это segfaulting? - person wish_it_was_python; 05.03.2010
comment
@wish_it_was_python: это из-за использования negs** в функции сравнения, см. мой отредактированный ответ. - person interjay; 06.03.2010
comment
Вам не нужен актерский состав: const negs *ia = a; const negs *ib = b; работает. - person Alok Singhal; 06.03.2010