简体   繁体   English

mmap() 导致 C 中的分段错误

[英]mmap() causing segmentation fault in C

I'm pretty sure my mistake is very evident, but I just can't seem to find where the problem is.我很确定我的错误非常明显,但我似乎无法找到问题所在。

I'm learning how to use mmap() in C, everything looks correct to me, but I get a segmentation fault.我正在学习如何在 C 中使用mmap() ,一切对我来说都是正确的,但是我遇到了分段错误。

Here is my code:这是我的代码:

int n=50;
char * tab = mmap(NULL, n, PROT_READ | PROT_WRITE, MAP_SHARED, -1, 0);

for(int i=0; i<n; i++)
{
   tab[i] = 1;
}

Using valgrind , I get an error saying "Invalid write of size 1" at the line where I do tab[i]=1 , (I have tried replacing 1 by '1' thinking that maybe a char has a smaller size than an int , but still get the same error), followed by "Address 0xfffff..ff is not stack'd, malloc'd, or (recently) free'd".使用valgrind ,我在执行tab[i]=1的行收到一条错误消息,提示“大小 1 的无效写入”,(我曾尝试将1替换为'1'认为 char 的大小可能小于int ,但仍然得到相同的错误),然后是“地址0xfffff..ff不是堆栈的、malloc 的或(最近)释放的”。

I have no idea where my mistake is.我不知道我的错误在哪里。 Can somebody help me find it?有人可以帮我找到吗?

From man 2 mmap :来自man 2 mmap

The contents of a file mapping (as opposed to an anonymous mapping; see MAP_ANONYMOUS below), are initialized using length bytes starting at offset offset in the file (or other object) referred to by the file descriptor fd .文件映射的内容(与匿名映射相反;请参阅下面的MAP_ANONYMOUS )使用从文件描述符fd引用的文件(或其他对象)中的偏移offset开始的length字节进行初始化。

I suppose that you are trying to create an anonymous mapping (ie not backed by a file).我想您正在尝试创建一个匿名映射(即不受文件支持)。 In such case, you need to add MAP_ANONYMOUS to the flags , otherwise the system will try to read from the specified fd , which is invalid ( -1 ) and will fail.在这种情况下,您需要MAP_ANONYMOUS添加到flags ,否则系统将尝试从指定的fd读取,这是无效的 ( -1 ) 并且会失败。

The correct code is:正确的代码是:

char *tab = mmap(NULL, n, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (tab == MAP_FAILED) {
    perror("mmap");
    exit(1);
}

For the future, note that you can easily detect the error like I did above with a simple call to perror() in case the returned value indicates failure.对于未来,请注意,如果返回值指示失败,您可以像上面一样通过简单地调用perror()轻松检测错误。 In your case it should have printed the following:在您的情况下,它应该打印以下内容:

mmap: Bad file descriptor

Checking the manual again you can see in the "ERRORS" section:再次检查手册,您可以在“错误”部分看到:

EBADF : fd is not a valid file descriptor (and MAP_ANONYMOUS was not set). EBADF : fd不是有效的文件描述符(并且未设置MAP_ANONYMOUS )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM