使用mmap()而不是malloc()

时间:2016-10-19 08:30:20

标签: c malloc mmap

我正在尝试完成使用系统调用完成的练习,并且需要为struct *分配内存。我的代码是:

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

为了澄清,我不能使用malloc(),但可以使用mmap()。我在Netbeans的Windows上没有遇到任何问题,但现在我正在Ubuntu上从命令行编译和运行我得到了#34; Segmentation Fault"每次我尝试访问它。

它是否有理由在一个而不是另一个上工作,并且mmap()是以这种方式分配内存的有效方式?我担心的是我最初会为每个mmap()电话分配大块内存,现在我无法让它运行。

此外,我的mmap返回的错误是22 - 无效参数(我在编写问题时进行了一些故障排除,因此错误检查不在上面的代码中)。地址为0,自定义SIZEOF()函数在其他mmap参数中有效,我使用MAP_ANONYMOUS,因此fdoffset参数必须分别为-1和0。

PROT_READ|PROT_WRITE部分有问题吗?

2 个答案:

答案 0 :(得分:6)

您需要在标志中指定MAP_PRIVATE。

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

来自manual page

  

flags参数确定是否对映射进行更新   映射相同区域的其他进程可见,以及是否   更新将传递到基础文件。这种行为是   由在flags中包含以下值中的一个确定:

您需要其中一个标志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)。

答案 1 :(得分:3)

mmap()的手册页说明您必须在MAP_SHARED参数中指定MAP_PRIVATEflags中的一个。在您的情况下,要像malloc()那样行事,您需要MAP_PRIVATE

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

(我还通过省略有害演员并将sizeof与实际变量匹配而不是其类型)来使这更加惯用C。