2

I am implementing IPC using shared memory in C linux. Here is my receiving process. It's receiving correct length but not the message. However sending process is properly sending it. Please see this and let me know the error.

//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 is

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

thanks :)

4
  • Deer Ghost-downvoter: explain why. Commented Mar 31, 2014 at 11:33
  • What's this supposed to do: memcpy(&rbuf->cp,rbuf+sizeof(int),rbuf->msglen); ? Where have your server placed the message you want to receive ? Commented Mar 31, 2014 at 11:35
  • (m = shmat(shmid, NULL, 0)) == (message_buf *) -1 where m is a ptr to msg_buf. and then m->cp="message entered by user". Also I have changed rbuf->msglen to sizeof(*rbuf) to get the ptr to cp. Commented Mar 31, 2014 at 11:41
  • @user3392539 You overwrite cp in rbuf->cp=malloc(rbuf->msglen); so surely you cannot expect that pointer to contain the message anymore. Moreover, pointers are local to a process, you can't transfer a pointer across shared memory, as a pointer is only valid in the process that created it. Commented Mar 31, 2014 at 13:03

2 Answers 2

5

You read a char* from the shared memory region. However, that points to a buffer allocated with malloc, in the remote process. As such it points to the process heap of local to that other process.

This is simply undefined behaviour.

Instead, make the character buffer part of the shared memory data structure:

//header files
#define MAX_SH_BUFSIZE 1024
//
typedef struct msgbuf1
{
    int msglen;
    char cp[MAX_SH_BUFSIZE];
} message_buf;
Sign up to request clarification or add additional context in comments.

8 Comments

can't I make it dynamic. I mean using *cp instead of character array. and that's why I used memcpy in my prog above
No. As he said, the buffer returned by malloc is private to the process that called it.
@JonathonReinhart to me that doesn't make much sense. Why would he be sharing opaque pointers that don't refer to same process space? Also, he's calling memcpy on the stuff. So either it is this (as I describe in my answer) or the OP is completely confused as to what a struct layout is and how the cp member functions. The more I look at the code I think it's both
Sorry, I was actually replying to the OP in that comment.
Yes it does. And your struct contains exactly two elements: msglen and cp whose value will be physically located in that segment. HOWEVER, cp points to an address outside that area. Of course, we can't see the 'server' side of the code, so it is "possible" that you store something else entirely, but char* suggests that cp is intended to contain a pointer to character. So your problem is that you have two pointers, and you're only taking care of the one)
|
0

The problem is with the malloc. malloc addresses have scope till he process not the shared memory. You should not use malloc in shared memory.

Method 1.

Instead use a fix size character array as below:

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

Set MESSAGE_SIZE as the maximum size of data you would require.

Method 2. Create a sufficient size shared memory. Make you own malloc and free function which would provide memory from shared memory as and when require. For this you need to keep track of free list, which store the free memory space in the shared memory.

You can divide your shared memory into chunks of like say 256bytes, 512bytes and 1024bytes. Now whenever you require memory the custom malloc function for shared memory shoud hold the logic to provide memory efficiently.

Custom free function would free the shared memory released by program along with adding that chunk(s) in free list

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.