访问共享内存时出现分段错误

时间:2019-07-31 11:25:25

标签: linux ipc shared-memory

我想为我的应用程序使用共享内存。 我有两个过程。一个将创建共享内存(写入器),一个将附加到此共享内存以读取它(读取器)。 从作者的角度来说,我可以在共享内存中进行写入。但是从阅读器代码中,我可以成功获取并附加到内存。 但是,当我尝试从该内存中读取数据时,会产生段错误。

作者代码:

#include<stdio.h>

#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/types.h>
#include<string.h>
#include<errno.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>

#define BUF_SIZE 4096
#define SHM_KEY 0x1239
#define MAX_FIFO_ELEMENTS   100


struct stcomndstruct
{
    unsigned char status;
    unsigned int command_id;
    unsigned int event_id;
    unsigned int event_subid;
    unsigned int datasize;
    unsigned int offset;
};

struct stcirFIFO
{
     int head;
     int tail;
    //unsigned int status;
    struct stcomndstruct command[MAX_FIFO_ELEMENTS];
};



int main(int argc, char *argv[]) {
   int shmid, numtimes,i=0;
   struct stcirFIFO *shmp;
   char *bufptr;
   int spaceavailable;
   shmid = shmget(SHM_KEY, sizeof(struct stcirFIFO), 0644|IPC_CREAT);
   if (shmid == -1) {
      perror("Shared memory");
      return 1;
   }

   // Attach to the segment to get a pointer to it.
   shmp = shmat(shmid, NULL, 0);
   if (shmp == (void *) -1) {
      perror("Shared memory attach");
      return 1;
   }
   printf("\n WRITER ADDRESS %d",shmp);
   /* Transfer blocks of data from buffer to shared memory */
   shmp->head=0;
   for(i=0;i<60;i++)
   {
       shmp->head=shmp->head+1;
       sleep(1);
   }
   spaceavailable = BUF_SIZE;

   printf("Writing Process: Wrote %d times\n", numtimes);

sleep(10);
   if (shmdt(shmp) == -1) {
      perror("shmdt");
      return 1;
   }

   if (shmctl(shmid, IPC_RMID, 0) == -1) {
      perror("shmctl");
      return 1;
   }
   printf("Writing Process: Complete\n");
   return 0;
}

阅读器代码捕捉:

#define KEY_FIFO_VAR_SH_MEM 0x1239
void reader()
{
int shmid,i;
    struct stcirFIFO *shmp;
    printf("\n\n*******shared mem init called\n");
    shmid = shmget(KEY_FIFO_VAR_SH_MEM, sizeof(struct stcirFIFO), 0644|IPC_CREAT);
    if (shmid == -1) {
        perror("Shared memory");
        return 1;
    }else
    {
        printf("\nLocate sucessfull...");
    }

    // Attach to the segment to get a pointer to it.
    shmp = shmat(shmid, NULL, 0);
    if (shmp == (void *) -1) {
        perror("Shared memory attach");
        return EXIT_FAILURE;
    }else
    {


        printf("\nAttach sucessfull...address %d",shmp);
        printf("address of head %d",&(shmp->head));

    }
    for(i=0;i<10;i++)
    {
        printf("Read Value %d",*shmp);
        sleep(1);
    }
}

跟踪日志:

write(1, "\n\n*******shared mem init called", 31

*******shared mem init called) = 31
write(1, "\n", 1
)                       = 1
shmget(0x1239, 2408, IPC_CREAT|0644)    = 13762590
write(1, "\nLocate sucessfull...", 21
Locate sucessfull...)  = 21
shmat(13762590, NULL, 0)                = 0x7f4c22a71000
write(1, "\nAttach sucessfull...address 581"..., 38
Attach sucessfull...address 581373952) = 38
write(1, "address of head 581373952", 25address of head 581373952) = 25
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x22a71000} ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault (core dumped)

2 个答案:

答案 0 :(得分:0)

访问未授权的内存时发生分段错误。 shmget()返回与自变量键的值关联的System V共享内存段的标识符。它可以用于获取先前创建的共享内存段的标识符(当shmflg为零且键的值不为IPC_PRIVATE时),或用于创建新集合。

因此,在接收方,您应该在shmget()中使用相同的密钥; shmid = shmget( KEY_FIFO_VAR_SH_MEM ,sizeof(struct stcirFIFO),0644 | IPC_CREAT);

答案 1 :(得分:0)

    struct stcirFIFO *shmp;

    ...

    printf("Read Value %d",*shmp);

由于shmp的类型为struct stcrFIFO *,因此您尝试使用struct stcrFIFO格式说明符将printf传递给%d。期望有int