我正在尝试完成一个系统调用的练习,需要为结构体*分配内存。我的代码是:
myStruct * entry = (myStruct *)mmap(0, SIZEOF(myStruct), PROT_READ|PROT_WRITE,
MAP_ANONYMOUS, -1, 0);
澄清一下,我不能使用malloc()
,但可以使用mmap()
。我在Netbeans的Windows上没有这个问题,但是现在我在Ubuntu上编译和从命令行运行,每次我试图访问它时,我都会得到"分段错误"。
是否有一个原因,为什么它将工作在一个,而不是另一个,是mmap()
在这种方式分配内存的有效方式?我担心的是,我最初将为每个mmap()
调用分配大块内存,现在我只是无法让它运行。
此外,我的mmap返回的错误是22 -无效参数(我在编写问题时做了一些故障排除,因此错误检查不在上面的代码中)。地址为0,自定义SIZEOF()
函数在其他mmap参数中工作,我使用MAP_ANONYMOUS
,因此fd
和offset
参数必须分别为-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);
从手册页:
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 = %dn", entry, entry->a);
}
return 0;
}
(当然,上面没有MAP_PRIVATE
,这是一个很好的例子,说明您可能已经提供了一个MCVE。这使得其他人更容易帮助您,因为他们可以确切地看到您所做的工作,并测试他们提出的解决方案。
mmap()
的手册页说,您必须在flags
参数中指定MAP_SHARED
和MAP_PRIVATE
中的一个。在您的例子中,要像malloc()
一样,您需要MAP_PRIVATE
:
myStruct *entry = mmap(0, sizeof *entry,
PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
(我还通过省略有害的强制转换并将sizeof
匹配到实际变量而不是其类型,使其更符合C的习惯用法)