shm_open 分段错误和权限失败

shm_open segmentation fault and permission failed

我是 Linux 的新手,我正在尝试创建一个共享内存对象,它存储在子进程中计算的 collat​​z 猜想并在父进程中打印它。我已经阅读了命令的手册页。 当我创建对象时,它会打印权限被拒绝和分段错误(核心已转储)。只有一次它以某种方式通过了那一步然后我得到映射失败 error.I 我在虚拟机上使用 ubuntu 18.04

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<sys/wait.h>
#include<sys/stat.h>

int main(int argc,char** argv)
{
pid_t pid;
pid = fork();
int page_size = 4096;
char obj[] = "name";
int num = atoi(argv[1]);
    if(num < 1)
{
    printf("Please input a greater number\n");
    return 0;
}

if(pid < 0)
{
    fprintf(stdout,"Fork failed\n");
}
else if(pid == 0)
{
    int fd1 = 0;
    void *ptr1 = NULL;
    fd1 = shm_open(obj,O_CREAT|O_TRUNC,S_IRWXU);
    if (fd1 == -1)
    {
        perror("error:");
        exit(0);
    }
    ftruncate(fd1,page_size);
    ptr1 = mmap(0,page_size,PROT_WRITE,MAP_SHARED,fd1,0);
    if(ptr1 == MAP_FAILED)
    {
        fprintf(stdout,"Mapping failed");
        exit(0);
    }
    else
    {
        while(num != 1)
        {
            if(num%2 == 0)
                num = num / 2;
            else
                num = (num * 3) + 1;

            sprintf(ptr1,"%d, ",num);
        }
    }
}
else
{
    wait(NULL);
    int fd = 0;
    void *ptr = NULL;
    shm_open(obj,O_RDONLY,S_IRWXU);
    ptr = mmap(0,page_size,PROT_READ,MAP_SHARED,fd,0);
    char *pr = (char *)ptr;
    fprintf(stdout,pr);
    shm_unlink(obj);

}
return 0;
}

您的代码需要进行一些更改,一些是为了更好的编程实践,一些是为了修复实际功能:

#include <all.h>

int main(int argc, char **argv) {
    pid_t pid;
    pid = fork();
    int page_size = 4096;
    char obj[] = "name";
    // check argc otherwise you'll segfault
    if (argc < 2) {
        printf("Please provide a second argument.\n");
        // if the program errors it should not return 0
        return 1;
    }
    int num = atoi(argv[1]);
    if (num < 1) {
        printf("Please input a greater number\n");
        return 1;
    }

    if (pid < 0) {
        // no need for fprintf(stdout
        printf("Fork failed\n");
    } else if (pid == 0) {
        int fd1 = 0;
        char *ptr1 = NULL;
        // we need to open with O_RDWR otherwise mmap will fail
        fd1 = shm_open(obj, O_CREAT | O_TRUNC | O_RDWR, 0666);
        if (fd1 == -1) {
            perror("shm_open error");
            return 1;
        }
        ftruncate(fd1, page_size);
        // cast it to char* directly, no need for void pointer stuff
        ptr1 = (char *) mmap(0, page_size, PROT_WRITE, MAP_SHARED, fd1, 0);
        if (ptr1 == MAP_FAILED) {
            // perror for debugging
            perror("mmap error");
            printf("Mapping failed.\n");
            return 1;
        } else {
            while (num != 1) {
                if (num % 2 == 0)
                    num = num / 2;
                else
                    num = (num * 3) + 1;

                // we need to shift the pointer so it stops truncating
                ptr1 += sprintf(ptr1, "%d, ", num);
            }
        }
    } else {
        wait(NULL);
        // move these to one like and cast to char* directly
        int fd = shm_open(obj, O_RDONLY, S_IRWXU);
        char *ptr = (char*) mmap(0, page_size, PROT_READ, MAP_SHARED, fd, 0);
        // no need for fprintf(stdout, and also use %s\n as a format to add a newline
        printf("%s\n", ptr);
        shm_unlink(obj);
    }
    return 0;
}