2015-03-23 4 views
1

Я новичок в файлах сопоставления памяти и немного запутался. Можно ли сопоставлять файлы, большие, чем общий объем памяти, потому что, поскольку я понял, что отображение памяти использует запрос подкачки и будет содержать только актуальные страницы в памяти. Является ли это правильным, или мое приложение будет сбой при использовании большего объема, чем фактическая память.C/C++ - Файл карты памяти с помощью mmap

Благодаря

EDIT ОС: Ubuntu 14.04 LTS x86_64 App-разрядность: 64bit (я думаю: указатели 8 байт)

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

#define MEMORY_SIZE 300000000 

unsigned char *mem_buffer; 
void *start_ptr; 

void *my_malloc(int size) { 
    unsigned char *ptr = mem_buffer; 
    mem_buffer += size; 

    return ptr; 
} 

void *my_calloc(int size, int object_size) { 
    unsigned char *ptr = mem_buffer; 
    mem_buffer += (size * object_size); 

    return ptr; 
} 

void init(const char *file_path) { 
    int fd = open(file_path, O_RDWR, S_IREAD | S_IWRITE); 

    if (fd < 0) { 
     perror("Could not open file for memory mapping"); 
     exit(1); 
    } 

    start_ptr = mmap(NULL, MEMORY_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); 
    mem_buffer = (unsigned char *) start_ptr; 

    if (mem_buffer == MAP_FAILED) { 
     perror("Could not memory map file"); 
     exit(1); 
    } 

    printf("Successfully mapped file.\n"); 
} 

void unmap() { 
    if (munmap(start_ptr, MEMORY_SIZE) < 0) { 
     perror("Could not unmap file"); 
     exit(1); 
    } 

    printf("Successfully unmapped file.\n"); 
} 

Основной метод:

int main(int argc, char **argv) { 

    init(argv[1]); 

    unsigned char *arr = (unsigned char *) my_malloc(6); 
    arr[0] = 'H'; 
    arr[1] = 'E'; 
    arr[2] = 'L'; 
    arr[3] = 'L'; 
    arr[4] = 'O'; 
    arr[5] = '\0'; 

    unsigned char *arr2 = (unsigned char *) my_malloc(5); 
    arr2[0] = 'M'; 
    arr2[1] = 'I'; 
    arr2[2] = 'A'; 
    arr2[3] = 'U'; 
    arr2[4] = '\0'; 

    printf("Memory mapped string1: %s\n", arr); 
    printf("Memory mapped string2: %s\n", arr2); 

    struct my_btree_node *root = NULL; 

    insert(&root, arr, 10); 
    insert(&root, arr2, 20); 

    print_tree(root, 0, false); 

// cin.ignore(); 

    unmap(); 

    return EXIT_SUCCESS; 
} 
+0

Какова ценность errno после того, как mmap не удался? – Malkocoglu

+0

@Malkocoglu errno имеет значение 12 – aQuip

+0

@Malkocoglu Я переместил вопрос здесь 'http: // stackoverflow.com/questions/29213142/c-memory-map-a-b-tree', потому что на вопросы, заданные здесь, отвечает. – aQuip

ответ

2

Вот отрывок из The GNU C Library: Memory-mapped I/O

Поскольку mmapped страница может быть сохранена Вернемся к их файлу, когда физическая память низкая, возможно, mmap-файлы на порядок больше, чем физическая память и пространство подкачки. Единственным ограничением является адресное пространство. Теоретический предел составляет 4 ГБ на 32-битной машине, однако фактический предел будет меньше, поскольку некоторые области будут зарезервированы для других целей.

3

Возможно (и очень нормально), чтобы отобразить файлы, размер которых превышает общую сумму памяти, но ваше приложение должно быть в состоянии решить ее. У вас ограниченный диапазон адресов, если ваша система/приложение 32-разрядная. Ваша система & приложение должно быть 64-битным для адреса большего размера, чем файлы размером в несколько гигабайт ...

Обратите внимание: Даже если ваш файл небольшой, вы все равно не сможете его сопоставить. Может быть, вы потребляли ваше адресное пространство, просто выделение памяти для других целей (стько для потоков, памяти для буферов приложений/списков и т.д.)

+1

На самом деле это 4 ГБ, но на практике 2 ГБ или 3 ГБ в зависимости от режима адресации. –

+0

Должен ли я использовать 'mmap64' для использования всего 64-битного или' mmap'? – aQuip

+0

@Malkocoglu Проблема в том, что я получаю сообщение об ошибке «Не могу выделить память», если попытаюсь сопоставить больший размер, чем доступная память. Нужно ли вручную распаковывать, а затем сопоставлять с другим смещением для обработки большого файла? – aQuip