IPC在C中使用共享内存

时间:2014-03-31 11:15:51

标签: c linux ipc shared-memory

我在C linux中使用共享内存实现IPC。这是我的接收过程。它收到正确的长度但不是消息。但是发送过程正确地发送它。 请看这个,让我知道错误。

//header files
#include "/home/user/msgbuf.h"
#define SHMSZ    127
int main()
{
    int shmid;
    key_t key;
    message_buf *rbuf;
    rbuf=malloc(sizeof(*rbuf));
    key = ftok("/home/user/shmem",17);

    if ((shmid = shmget(key, SHMSZ, 0666)) < 0)
    {       perror("shmget");
            exit(1);
    }
    printf("\nShared Memory Id = %d\n",shmid);
    if ((rbuf = shmat(shmid, NULL, 0)) == (message_buf *) -1)
    {       perror("shmat");
            exit(1);
    }
    printf("\nMEMORY SEGMENT ATTACHED TO THE CLIENT'S PROCESS\n");

/* Now read what the server put in the memory */
    printf("\nmsglen = %d",rbuf->msglen);  //this is correct
    rbuf->cp=malloc(rbuf->msglen);
    memcpy(&rbuf->cp,rbuf+sizeof(int),sizeof(*rbuf));
    printf("\nMESSAGE :: %s",rbuf->cp); //MESSAGE :: null
    fflush(stdout);
    shmdt(&shmid);
    printf("\nMEMORY SEGMENT %d DETACHED\n",shmid);
    return 0;
}

msgbuf.h是

typedef struct msgbuf1
{
    int msglen;
    char *cp;
}message_buf;

谢谢:)

2 个答案:

答案 0 :(得分:5)

您从共享内存区域读取char *。但是,这指向在远程进程中使用malloc分配的缓冲区。因此,它指向其他进程的本地进程堆。

这只是未定义的行为。

相反,将字符缓冲区作为共享内存数据结构的一部分:

//header files
#define MAX_SH_BUFSIZE 1024
//
typedef struct msgbuf1
{
    int msglen;
    char cp[MAX_SH_BUFSIZE];
} message_buf;

答案 1 :(得分:0)

问题出在malloc上。 malloc地址具有作用域,直到他不处理共享内存为止。您不应在共享内存中使用malloc。

方法1。

请使用固定大小的字符数组,如下所示:

typedef struct msgbuf1
{
    int msglen;
    char cp[MESSAGE_SIZE];
}message_buf;

将MESSAGE_SIZE设置为所需的最大数据大小。

方法2。 创建足够大小的共享内存。 使您拥有malloc和free函数,这些函数将在需要时从共享内存中提供内存。 为此,您需要跟踪空闲列表,这些空闲列表将可用内存空间存储在共享内存中。

您可以将共享内存划分为256bytes,512bytes和1024bytes之类的块。 现在,每当您需要内存时,共享内存的自定义malloc函数都应保持有效地提供内存的逻辑。

自定义免费功能将释放程序释放的共享内存,并将该块添加到空闲列表中