2016-10-19 5 views
6

Я пытаюсь выполнить упражнение, выполняемое с помощью системных вызовов, и выделить память для структуры *. Мой код:Использование mmap() вместо malloc()

myStruct * entry = (myStruct *)mmap(0, SIZEOF(myStruct), PROT_READ|PROT_WRITE, 
MAP_ANONYMOUS, -1, 0); 

Чтобы уточнить, я не могу использовать malloc() но можно использовать mmap(). У меня не было никаких проблем с этим в Windows в Netbeans, но теперь я компилирую и запускаю из командной строки в Ubuntu. Я получаю «Ошибка сегментации» каждый раз, когда я пытаюсь получить к нему доступ.

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

Кроме того, ошибка, возвращаемая моим mmap, равна 22 - Invalid Argument (я сделал некоторое устранение неполадок при написании вопроса, чтобы проверить ошибку в приведенном выше коде). Адрес 0, пользовательская функция SIZEOF() работает в других аргументах mmap, я использую MAP_ANONYMOUS, поэтому параметры fd и offset должны быть равны -1 и 0 соответственно.

Есть что-то не так с разделами PROT_READ|PROT_WRITE?

+2

Просто дикая догадка, если вы используете '4096' или' 8192' или какую-то другую силу из двух вместо 'SIZEOF (myStruct)', это работает? –

+1

Я думаю, что ошибка связана с вашим 'SIZEOF()'.и вы должны добавить 'MAP PRIVATE' –

+0

' SIZEOF() 'неверно, фактический элемент пишется' sizeof() 'I.E. в Нижнем регистре. – user3629249

ответ

6

В ваших флагах необходимо указать MAP_PRIVATE.

myStruct * entry = (myStruct *)mmap(0, SIZEOF(myStruct), 
     PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 

От manual page:

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

Вы должны точно один из флагов MAP_PRIVATE или MAP_SHARED - но вы не дали один из них.

Полный пример:.

#include <sys/mman.h> 
#include <stdio.h> 

typedef struct 
{ 
    int a; 
    int b; 
} myStruct; 

int main() 
{ 
    myStruct * entry = (myStruct *)mmap(0, sizeof(myStruct), 
      PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 

    if (entry == MAP_FAILED) { 
     printf("Map failed.\n"); 
    } 
    else { 
     entry->a = 4; 
     printf("Success: entry=%p, entry->a = %d\n", entry, entry->a); 
    } 
    return 0; 
} 

(выше, без MAP_PRIVATE конечно, является хорошим примером того, что вы могли бы при условии, как в MCVE Это делает его гораздо проще для других, чтобы помочь вам, поскольку они могут точно видеть, что вы сделали, и проверить их предлагаемые решения. Вы всегда должны предоставлять MCVE).

+0

Вот оно, я неправильно прочитал инструкцию! Я начал с MAP_PRIVATE, переместился в MAP_ANONYMOUS, нужен был ... Спасибо большое. –

3

В справочной странице для mmap() указано, что вы должны точно указать один из MAP_SHARED и MAP_PRIVATE в аргументе flags. В вашем случае, чтобы действовать как malloc(), вы хотите MAP_PRIVATE:

myStruct *entry = mmap(0, sizeof *entry, 
         PROT_READ|PROT_WRITE, 
         MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 

(Я также сделал это более идиоматический C, исключив вредное бросание и сопоставление sizeof фактических переменный, а не ее типа) ,

+0

Спасибо! Я должен работать над своими навыками чтения вручную. –