我的C代码中有关于共享内存的问题.

我有一个C代码,它不能像我预期的那样工作:

#include "sys/ipc.h"
#include "sys/shm.h"

#include "unistd.h"
#include "sys/types.h"
#include "sys/wait.h"

#include "stdio.h"
#include "stdlib.h"

int main(){
    key_t key = ftok("shmfile.txt", 65);
    int shmid = shmget(key, sizeof(int), IPC_CREAT);
    if (fork() != 0){
        int * ptr = (int *) shmat(shmid, 0, 0); // This line returns -1
                            // This only happened
                            //  to parrent
        printf("shmid parrent = %d\n", shmid);
        perror("Error ");
        *ptr = 6;
        shmdt(ptr);
        wait(NULL);
        shmctl(shmid, IPC_RMID, NULL);
    }
    else{
        printf("shmid child = %d\n", shmid);
        int * ptr = (int *) shmat(shmid, 0, 0); // Works as expected
        printf("ptr address = %p\n", ptr);      
        shmdt(ptr);
        printf("Now child can exit normally");
    }
    return 0;
}

结果如下(Gdb):

shmid parrent = 45
Error : Permission denied
shmid child = 45
ptr address = 0xffffffffffffffff
Now child can exit normally
Program received signal SIGSEGV, Segmentation fault.
0x00005555555552d0 in main () at main_2.c:20
20          *ptr = 6;

我希望父进程和子进程都能正常工作.只有子进程正常退出.我不确定父进程有什么问题.非常感谢!

更新1:父进程和子进程中的PTR始终为(void *) -1.我不知道如何让shmat()不返回那个值.

更新2:文件"shmfile.txt"与main可执行文件位于同一位置.

推荐答案

You should specify permission used to create the shared memory.
For instance using

int shmid = shmget(key, sizeof(int), IPC_CREAT | 0666);

shmget人的文档中可以看到:

除了上述标志外,最低有效的9位 Shmflg指定授予所有者、组和 其他.这些位具有相同的格式和相同的含义, 作为OPEN(2)的模式参数.目前,执行权限 不被系统使用.

通过这种修改,您的代码就可以运行了.

Ideone

C++相关问答推荐

如何在C中通过转换为char * 来访问float的字节表示?

函数指针始终为零,但在解除引用和调用时有效

在Windows上构建无聊的SSL x64

GCC:try 使用—WError或—pedantic using pragmas

Malloc(sizeof(char[Length]))是否不正确?

编译的时候g++通常会比GCC慢很多吗?

二进制计算器与gmp

C++中矢量类型定义和数据保护的高效解决方案

理解C版宏(看起来像未声明的变量?)

为什么我可以在GCC的标签后声明变量,但不能声明Clang?

用C++实现余弦函数

如何使用C++在控制台中以彩色打印被阻止的客户端

<;unistd.h>;和<;sys/unistd.h>;之间有什么区别?

为什么Linux无法映射这个PT_LOAD ELF段?

向左移位3如何得到以字节为单位的位数?

共享目标代码似乎不能在Linux上的进程之间共享

传递给函数的 struct 中的数组

为什么这个代码的最后一次迭代不能正常工作?

通过GTK';传递回调参数;s g_signal_connect()导致C中出现意外值

为什么使用 C 引用这个 char 数组会导致 Stack smasing?