Linux共享内存分段错误

时间:2016-07-15 06:03:31

标签: c linux ipc shared-memory

我正在学习共享内存,并创建了这个示例程序来测试出来

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

然而,当我运行它时,我得到分段错误。似乎我对共享内存的指针不正确。也没有任何东西从子进程中的无限循环中打印出来。

ankit@ankit-ThinkPad-W530:~/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)

这里出了什么问题?

1 个答案:

答案 0 :(得分: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>