使用 mmap() 而不是 malloc()

Using mmap() instead of malloc()

我正在尝试完成一个通过系统调用完成的练习,需要为结构 * 分配内存。我的代码是:

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

澄清一下,我不能使用 malloc() 但可以使用 mmap()。我在 Netbeans 的 Windows 上对此没有任何问题,但是现在我正在编译并从 Ubuntu 上的命令行 运行ning 我每次尝试都会得到 "Segmentation Fault"访问它。

为什么它只适用于一个而不适用于另一个,并且 mmap() 是一种以这种方式分配内存的有效方法吗?我担心的是最初我要为每个 mmap() 调用分配大块内存,现在我无法将它分配到 运行.

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

PROT_READ|PROT_WRITE 部分有问题吗?

您需要在标志中指定 MAP_PRIVATE。

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

来自manual page

The flags argument determines whether updates to the mapping are visible to other processes mapping the same region, and whether updates are carried through to the underlying file. This behavior is determined by including exactly one of the following values in 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)。

mmap() 的手册页说您必须在 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 更加地道。