Многопоточный массив C qsort char

Я пытаюсь отсортировать некоторые записи по их ключам в C.

Существует M записей, и синтаксис каждой записи:

KEY v -------- DATA v

1234abcd. abcdefghijklmnopqrstuvwxyzzzzzzzzzz

Каждая запись имеет 8-байтовое шестнадцатеричное значение ключа, за которым следуют 64 байта данных.

Процесс выглядит следующим образом:

  • открыть файл
  • создать карту памяти файла
  • теперь в памяти с гигантским символом * создайте N потоков
  • использовать N потоков для сортировки M/N записей
  • объединить соседние отсортированные разделы, т.е. 0 и 1, 2 и 3

Прямо сейчас я пытаюсь нацелить ключ в функции qsort, но получаю ошибку сегментации.

Мой код после успешного открытия файла.

if((fstat(fileNum, &sb)) == -1) {
         printf("fstat fail");
         exit(-1);
    }  
int sb_size = sb.st_size;
int num_records = sb_size/REC_SIZE;

printf("SB SIZE: %d\n", sb_size);
printf("num_records: %d\n", num_records);

addr = (char *)mmap(NULL, sb_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fileNum, 0);

if (addr == MAP_FAILED) {
    close(fileNum);
    perror("Error mmapping the file");
    exit(EXIT_FAILURE);
}


int num_records_per_thread = num_records/num_threads;
printf("Number of Records per Thread = %d\n", num_records_per_thread);
qsort(addr, num_records_per_thread, REC_SIZE, compare);

int compare(const void *a, const void *b) {
        struct mRecord rec1, rec2;
        char *keya;
        strncpy(keya, (char *)a, 8);
        printf("in Compare: first 8 bytes are: %s", keya);
        return 1;
    }

Это дает мне ошибку сегментации. Как я могу просто нацелить ключи и отсортировать их? Большое спасибо.


person Klisko    schedule 13.04.2015    source источник
comment
Не имеет отношения к вашему вопросу и проблеме, но при проверке errno делайте это сразу после сбойного вызова функции, самое главное, не вызывайте другую функцию, которая может изменить errno между ними. Я упоминаю об этом потому, что если mmap не удается, вы вызываете close, что может также завершиться ошибкой и, следовательно, изменить значение errno. Позвоните perror до close.   -  person Some programmer dude    schedule 14.04.2015


Ответы (1)


1) Нельзя копировать переменную a в keya с помощью strncpy, потому что keya — это неинициализированный указатель!

2) Функция сравнения должна возвращать значение сравнения!

Затем внутри сравнения функций вы можете написать:

return strncmp( (char *)a, (char *)b, 8 ); //8 is the key length!
person Sir Jo Black    schedule 14.04.2015
comment
Я должен был уточнить. Я еще не реализовал функцию сравнения. Я просто хотел посмотреть, как выглядят данные, поступающие в функцию. Если бы я сделал printf(a = %s, a); Я бы получил весь массив символов, а не только одну запись. Сорт не работает. - person Klisko; 14.04.2015
comment
Ok! Затем вы должны объявить: char keya[9], а не char * keya. Если вы используете char * keya, он указывает случайным образом в памяти, он не назначается! (Я думаю, что strncpy также должен быть другим, может быть, 9, а не 8, но я не уверен) - person Sir Jo Black; 14.04.2015
comment
Ах разобрался. Я выполнил отладку с помощью char test[8] = a и обнаружил, что проблема связана с размером моей записи. Спасибо большое - person Klisko; 14.04.2015