LINUX.ORG.RU

mmap и указатели

 ,


0

1

Имеется реализация двусвязного динамического списка. Структуры, описывающие его примерно такие:

struct node {
    int value;
    int size;
    struct node* next;
    struct node* prev;
};
struct dlist {
    struct node* head;
    struct node* tail;
};
Ну и соответствующие функции создания списка, добавления элемента, удаления элемента и прочего имеются.

Нужно уже созданный список заммапить в файл, а потом его прочитать. Сам я пытался записывать через memcpy и через поэлементное копирование. Но как-то не вышло. Как правильно это сделать?



Последнее исправление: cetjs2 (всего исправлений: 1)

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

именно заммапить? А почему просто не записать в файл int value и int size функцией fwrite(3)? (next и prev писать не нужно, ибо порядок записей и так сохраниться).

drBatty ★★
()

у тебя указатели похерятся скорее всего, так что смысл этого действа? Лучше просто value и size пиши в файл.

anonymous
()
Ответ на: комментарий от drBatty

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

memnek
() автор топика

Какое-то странное задание. Указатели всё равно похерятся же при чтении.

Можно найти минимальную общую область памяти, в которую помещается список со всеми нодами, создать файл, приммапить его (размер известен), memcpy-шнуть эту общую область в ммап, разммапить...

А, и ещё head сохранить как-то отдельно надо. Если он фиксированного размера, то можно его memcpy-шнуть отдельно в начало ммапленной области. Итого размер = (размер_хедера + общий_размер_области).

schizoid ★★★
()
Последнее исправление: schizoid (всего исправлений: 1)
Ответ на: комментарий от drBatty

Инкрементирую предложение этого оратора.

false ★★★★★
()

Как правильно это сделать?

Указатели не переживут копирование в mmap'нутый файл и обратно (так как положение mmap'нутого файла в памяти в следующий раз может быть разным).

Поэтому вместо указателей надо хранить смещения относительно начала смапленной области памяти.

struct node {
    int value;
    int size;
    size_t next_offset;
    size_t prev_offset;
};
struct dlist {
    size_t head_offset;
    size_t tail_offset;
};

void * mmaped_region_start;

node * node_get_next(node * n)
{
    return (node*)(mmaped_region_start + n->next_offset);
}

dmitry_vk ★★★
()
Ответ на: комментарий от memnek

1. считаешь, сколько у тебя структур в списке.
2. умножаешь это число на sizeof(node), и делаешь кусок памяти такого размера mmap'ом.
3. берёшь первую структуру, копируешь в выделуную память, prev ставишь в 0, next ставишь в sizeof(node).
4. берёшь n-ую структуру, копируешь в выделуную память с оффсетом sizeof(node)*n, prev ставишь в sizeof(node)*(n-1), next ставишь в sizeof(node)*(n+1). n возростает последовательно от 1.
5. в последней структуре next ставишь в 0.

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

nanoolinux ★★★★
()

Не изобретайте валосипед, используйте <sys/queue.h> !

beastie ★★★★★
()
Ответ на: комментарий от memnek

студентота, задание такое.

неправильное задание. может это и есть правильный ответ?

а вот с указателями беда.

замапь массив из 100500 структур. В качестве «указателя» юзай номер структуры. можно свой аллокатор сделать (ищем структуру, где prev == -1, её используем как свободную. При освобождении ставим prev ← -1. при поиске можно юзать битовую карту в дырах, ну или проще «метод следующего подходящего» (next fit)).

drBatty ★★
()

Нужно уже созданный список заммапить в файл

Может быть я ошибаюсь, но ведь не обязательно список занимает последовательную область памяти, т.е. между элементами списка могут быть всякие другие данные к нему не относящиеся. Но файл ммапится в память последовательно. Тогда я бы заммапил файл и обходя список от начала к концу закинул в заммаплунную область последовательно все данные (и только данные, без указателей), т.е. сделал бы из спсика массив. Обратно читал бы также - заммапил файл из массива воссоздал бы список.

no-such-file ★★★★★
()

Можно заmmapиться на фиксированный адрес и создавать структуры прямо там используя в качестве аллокатора mspaces из Doug Lea malloc (aka dlmalloc).

Darkman ★★★
()

Напиши уже функции "сериализации/десериализации": до mmap'ания свой список преобразуй в массив, затем сохраняй. Если прочитать надо — читаешь массив и преобразуешь его в список. Элементарно же!

Eddy_Em ☆☆☆☆☆
()

Ой, сорри, не посомтрел на теги.

Dudraug ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.