为什么此 POSIX 共享内存代码会出现分段错误?
Why does this POSIX shared memory code give a segmentation fault?
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/mman.h>
int main()
{
const int SIZE = 500;
const char *name = "name";
int fd;
char *ptr = NULL;
pid_t pid;
pid = fork();
if (pid < 0) {
fprintf(stderr, "Fork Failed");
return 1;
}
else if (pid == 0) {
fd = shm_open(name,O_CREAT | O_RDWR,0666);
ftruncate(fd, SIZE);
ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
sprintf(ptr, "%s", "Hello, World!\n");
return 0;
}
else {
wait(NULL);
fd = shm_open(name, O_RDONLY, 0666);
ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
printf("%s\n", (char *)ptr);
}
return 0;
}
我基本上是想在子进程中创建一些共享内存并从父进程访问它。
在子进程中,mmap
工作正常。当我使用 mmap
返回的指针进行打印时,它实际上打印了 Hello, World!
,但同样的打印给出了来自父级的段错误。
在父级 (pid != 0) 中您打开了对象 O_RDONLY,但是用 PROT_WRITE、MAP_SHARED 映射了它。删除 | PROT_WRITE 你很好。
您可能想偶尔检查 return 值是否有错误。
崩溃是由于摘录自 man:
O_RDONLY Open the object for read access. A shared memory object
opened in this way can be mmap(2)ed only for read
(PROT_READ) access.
您已尝试:
fd = shm_open(name, O_RDONLY, 0666);
// ^^^^^^^^
ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
// ^^^^^^^^^^^^ incorrect!
另请注意:您的 name
应遵循 man 可移植性建议:
For portable use, a shared memory object should be identified by a name
of the form /somename; that is, a null-terminated string of up to
NAME_MAX (i.e., 255) characters consisting of an initial slash,
followed by one or more characters, none of which are slashes.
最后,您有一些不必要的 (char *)
转换,并且总是错误检查您的 return 值。
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/mman.h>
int main()
{
const int SIZE = 500;
const char *name = "name";
int fd;
char *ptr = NULL;
pid_t pid;
pid = fork();
if (pid < 0) {
fprintf(stderr, "Fork Failed");
return 1;
}
else if (pid == 0) {
fd = shm_open(name,O_CREAT | O_RDWR,0666);
ftruncate(fd, SIZE);
ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
sprintf(ptr, "%s", "Hello, World!\n");
return 0;
}
else {
wait(NULL);
fd = shm_open(name, O_RDONLY, 0666);
ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
printf("%s\n", (char *)ptr);
}
return 0;
}
我基本上是想在子进程中创建一些共享内存并从父进程访问它。
在子进程中,mmap
工作正常。当我使用 mmap
返回的指针进行打印时,它实际上打印了 Hello, World!
,但同样的打印给出了来自父级的段错误。
在父级 (pid != 0) 中您打开了对象 O_RDONLY,但是用 PROT_WRITE、MAP_SHARED 映射了它。删除 | PROT_WRITE 你很好。 您可能想偶尔检查 return 值是否有错误。
崩溃是由于摘录自 man:
O_RDONLY Open the object for read access. A shared memory object
opened in this way can be mmap(2)ed only for read
(PROT_READ) access.
您已尝试:
fd = shm_open(name, O_RDONLY, 0666);
// ^^^^^^^^
ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
// ^^^^^^^^^^^^ incorrect!
另请注意:您的 name
应遵循 man 可移植性建议:
For portable use, a shared memory object should be identified by a name
of the form /somename; that is, a null-terminated string of up to
NAME_MAX (i.e., 255) characters consisting of an initial slash,
followed by one or more characters, none of which are slashes.
最后,您有一些不必要的 (char *)
转换,并且总是错误检查您的 return 值。