2016-07-15 154 views
3

我正在学习有关的共享内存,并创造了这个示例程序来测试的事情了Linux共享内存分段故障

//IPC - Shared Memory 

#include<stdio.h> 
#include<stdlib.h> 
#include<linux/ipc.h> 
#include<linux/msg.h> 
#include<linux/shm.h> 

int main(int argc, char* argv[]) 
{ 
    printf("setting up shared memory\n"); 

    key_t ipc_key; 
    int shmid; 
    int pid; 


    ipc_key = ftok(".",'b'); 

    if((shmid=shmget(ipc_key, 32, IPC_CREAT|0666))==-1) 
    { 
    printf("error creating shared memory\n"); 
    exit(1); 
    } 

    printf("shared memory created with id %d\n",shmid); 

    //fork a child process 
    pid = fork(); 
    printf("fork result %d\n",pid); 
    if(pid==0) 
    { 
    //child process 
    //attach the shared memory 
    int* shm_add_child = (int*)shmat(shmid, 0,0); 
    printf("child attached to shared mem at address %p\n",(void*)shm_add_child); 

    while(1) 
    { 
     printf("%d\n",*shm_add_child); 
     printf("a\n"); 
    } 

    //detach from shm 
    shmdt(shm_add_child); 
    } 
    else 
    { 
    //parent process 
    int* shm_add_parent; 

    shm_add_parent = (int*)shmat(shmid, 0,0); 
    printf("parent attached to shared mem at address %p\n",(void*)shm_add_parent); 
    *shm_add_parent = 10; 

    sleep(10); 

    //detach from shm 
    shmdt(shm_add_parent); 
    } 

    //remove shm 
    shmctl(shmid, IPC_RMID,0); 

    exit(0); 
} 

然而,当我运行它,我得到段错误。看来我对共享内存的指向是不对的。也没有什么是从子过程中的无限循环中打印出来的。

[email protected]:~/Desktop/week1_tasks$ ./ipc_sharedmem_a 
setting up shared memory 
shared memory created with id 5996570 
fork result 8703 
parent attached to shared mem at address 0xffffffff991aa000 
fork result 0 
child attached to shared mem at address 0xffffffff991aa000 
Segmentation fault (core dumped) 

这里怎么回事?

回答

6

我不确定你为什么要包含最后三个头文件。它们不是正确的标题,会给你shm函数的错误定义。在我的系统的gcc甚至会产生警告它提供了一些线索,有一个问题:

test.c:38:26: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 
    int* shm_add_child = (int*)shmat(shmid, 0,0); 
         ^
test.c:55:22: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 
    shm_add_parent = (int*)shmat(shmid, 0,0); 

相反,你应该只包括在shmat man page指定的人。具体如下:

#include<stdio.h> 
#include<stdlib.h> 

// Remove these headers 
//#include<linux/ipc.h> 
//#include<linux/msg.h> 
//#include<linux/shm.h> 

// Include these instead 
#include <sys/types.h> 
#include <sys/shm.h> 
+0

谢谢指出。我也被这个困惑了。但是我接下来的教程包含了Linux的教程,所以我和那些人一起去了。两者的区别究竟是什么? – Ankit

+0

我不知道这些标题是什么。它们看起来像内核和库中使用的头文件。包括上述头文件在内的 – kaylum

+0

摆脱了警告,但分段错误问题仍然存在 – Ankit