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

mmap() causing segmentation fault in C

我很确定我的错误很明显,但我似乎无法找到问题所在。

我正在学习如何在 C 中使用 mmap(),对我来说一切看起来都是正确的,但我遇到了分段错误。

这是我的代码:

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;
}

使用 valgrind,我在执行 tab[i]=1 的那一行收到错误提示 "Invalid write of size 1"(我尝试用 '1' 替换 1认为 char 的大小可能小于 int,但仍然会出现相同的错误),然后是 "Address 0xfffff..ff is not stack'd, malloc'd, or (recently) free'd".

我不知道我的错误在哪里。有人可以帮我找到吗?

来自 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添加到flags,否则系统将尝试从指定的fd读取,这是无效的(-1) 并且会失败。

正确的代码是:

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

对于未来,请注意,如果返回值指示失败,您可以像我上面那样通过简单调用 perror() 轻松检测到错误。在您的情况下,它应该打印以下内容:

mmap: Bad file descriptor

再次查看手册可以看到"ERRORS"部分:

EBADF: fd is not a valid file descriptor (and MAP_ANONYMOUS was not set).