我正在尝试完成使用系统调用完成的练习,并且需要为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
,因此fd
和offset
参数必须分别为-1和0。
PROT_READ|PROT_WRITE
部分有问题吗?
答案 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_PRIVATE
和flags
中的一个。在您的情况下,要像malloc()
那样行事,您需要MAP_PRIVATE
:
myStruct *entry = mmap(0, sizeof *entry,
PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
(我还通过省略有害演员并将sizeof
与实际变量匹配而不是其类型)来使这更加惯用C。