使用mmap()代替malloc()

7

我正在尝试使用系统调用完成一个练习,需要为一个结构体分配内存。我的代码如下:

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

为了澄清,我不能使用malloc(),但可以使用mmap()。在Windows的Netbeans中我没有任何问题,现在我正在Ubuntu的命令行中编译和运行,每次尝试访问时都会出现“分段错误”。

有没有原因可以解释为什么它在一个平台上可以工作而在另一个平台上就不行?mmap()是否是以这种方式分配内存的有效方法?我的担心是我将为每个mmap()调用分配大块内存,现在我只是无法运行它。

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

PROT_READ|PROT_WRITE部分是否存在问题?


2
只是一个猜测,如果你使用40968192或其他二的幂代替SIZEOF(myStruct),它是否有效? - Jabberwocky
1
我认为错误来自于你的 SIZEOF()。并且你应该添加 MAP PRIVATE - albttx
SIZEOF() 不正确,实际项目应为 sizeof(),即全部小写。 - user3629249
2
mmap()函数的第一个参数是一个地址指针,而不是一个整数。强烈建议使用NULL而不是0 - user3629249
4
请务必提供一个完整可编译的示例——最小化、完整性、可复现的示例(MCVE),一定要提供。 - davmac
2个回答

7

您需要在标志中指定MAP_PRIVATE。

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

根据手册页面

标志参数决定映射的更新是否对其他映射同一区域的进程可见,以及更新是否传递到底层文件。此行为由在标志中仅包含一个以下值来确定:

您需要确切地使用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;
}

以上内容是一个很好的MCVE示例,当然不包括MAP_PRIVATE。这是您可能提供的内容,可以让其他人更容易地帮助您,因为他们可以看到您所做的事情,并测试他们提出的解决方案。您应该始终提供一个MCVE。


这就是问题所在,我误读了手册!我一开始使用的是MAP_PRIVATE,然后转向使用MAP_ANONYMOUS,结果两个都需要用到...非常感谢。 - Sean Kelly

3
< p > mmap() 的 man 页面指出,在 flags 参数中必须精确指定 MAP_SHAREDMAP_PRIVATE 中的一个。在你的情况下,为了像 malloc() 一样运行,你需要选择 MAP_PRIVATE

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

(我还通过省略有害的强制类型转换并将 sizeof 与实际变量匹配而不是其类型,使这更符合惯用的C语言。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接