Чтение записей переменной длины из буфера - странные проблемы с памятью - PullRequest
2 голосов
/ 03 марта 2010

Я пытаюсь реализовать интенсивную быструю сортировку ввода-вывода (C ++ qsort) для очень большого набора данных. В интересах скорости, я хотел бы читать порцию данных за раз в буфер, а затем использовать qsort для сортировки внутри буфера. (В настоящее время я работаю с текстовыми файлами, но хотел бы в ближайшее время перейти на двоичные файлы.) Однако мои данные состоят из записей переменной длины, и для сортировки qsort необходимо указать длину записи. Есть ли способ стандартизировать это? Единственное, о чем я мог подумать, было довольно запутанным: моя программа в настоящее время читает из буфера, пока не достигнет символа перевода строки ('10' в ascii), перенося каждый символ в другой массив. Когда он находит перевод строки (разделитель во входном файле), он заполняет количество пробелов, оставшихся в буфере для этой записи (размер записи установлен на 30), нулевыми символами. Таким образом, я должен получить буфер, полный записей фиксированного размера, чтобы дать qsort.

Я знаю, что у моего подхода есть несколько проблем, одна из которых заключается в том, что он просто неуклюжий, а другая в том, что размер записи может быть больше 30, но обычно намного меньше. Есть ли лучший способ сделать это?

Кроме того, мой текущий код даже не работает. Когда я отлаживаю его, кажется, что он переносит символы из одного буфера в другой, но когда я пытаюсь распечатать буфер, он содержит только первую запись.

Вот мой код:

FILE *fp;
unsigned char *buff;
unsigned char *realbuff;
FILE *inputFiles[NUM_INPUT_FILES];
buff = (unsigned char *) malloc(2048);
realbuff = (unsigned char *) malloc(NUM_RECORDS * RECORD_SIZE);

fp = fopen("postings0.txt", "r");
if(fp)
{
    fread(buff, 1, 2048, fp);


    /*for(int i=0; i <30; i++)
     cout << buff[i] <<endl;*/

    int y=0;
    int recordcounter = 0;

    //cout << buff;
    for(int i=0;i <100; i++)
    {
        if(buff[i] != char(10))
        {
            realbuff[y] = buff[i];
            y++;
            recordcounter++;
        }        
        else
        {
            if(recordcounter < RECORD_SIZE)
                for(int j=recordcounter; j < RECORD_SIZE;j++)
                {
                    realbuff[y] = char(0);
                    y++;
                }
            recordcounter = 0;
        }
    } 

    cout << realbuff <<endl;   
    cout << buff;
}
else 
    cout << "sorry";

Большое спасибо, BSG

Ответы [ 2 ]

1 голос
/ 03 марта 2010

Функция qsort может работать только с записями фиксированной длины (как вы говорите). Чтобы отсортировать записи переменной длины, вам нужен массив указателей на них, а затем qsort отсортирует массив указателей. Это также может быть более эффективным, поскольку указатели перемещаются гораздо быстрее, чем большие куски данных.

То же самое относится и к std :: sort, что было бы рекомендовано, поскольку оно безопасно для типов. Просто убедитесь, что в качестве третьего аргумента указывается предикат сравнения (функция меньше единицы), в качестве аргументов которого используются указатели.

0 голосов
/ 03 марта 2010

Как насчет использования c ++ файловых потоков для анализа вашего файла?

Оформить заказ пример (название сайта странное, без обид !!), который возвращает запись в виде STL вектора и тогда вы можете использовать алгоритм сортировки STL .

...