Skip to content
Advertisement

Putting a Struct into Shared Memory

I have created two programs a server.c and a client.c. I have a struct that holds an age. I have got the programs working together to read the shared memory and to change the shared memory, however this only works when using one variable in the struct. As soon as i have more than one variable in the struct i get a segmentation fault.

Server.c

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

typedef struct People
{
    int age;
    int isDone;

} Person;

int main()
{
    Person aaron;
    Person *p_aaron;
    int id;
    int key = 5432;

    p_aaron = &aaron;
    (*p_aaron).age = 19;
    (*p_aaron).isDone = 0;

    if ((id = shmget(key,sizeof(aaron), IPC_CREAT | 0666)) < 0)
    {
        perror("SHMGET");
        exit(1);
    }


    if((p_aaron = shmat(id, NULL, 0)) == (Person *) -1)
    {
        perror("SHMAT");
        exit(1);
    }

    (*p_aaron).age = 19;


    printf("Shared Memory Age: %dn", (*p_aaron).age);
    *p_aaron = aaron;

    while ((*p_aaron).age == 19)
    {
        sleep(1);
    }

    printf("Shared Memory Age Turned To: %d", (*p_aaron).age);


    return 0;
}

Client.c

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>

typedef struct People
{
    int age;

} Person;

int main()
{
    Person aaron;
    Person *p_aaron;
    int id;
    int key = 5432;

    p_aaron = &aaron;

    id = shmget(key,sizeof(aaron), IPC_CREAT | 0644);
    p_aaron = shmat(id, NULL, 0);

    printf("%d", (*p_aaron).age);
    (*p_aaron).age = 21;


    return 0;
}

Error message from Server.c

SHMGET: Invalid argument

RUN FINISHED; exit value 1; real time: 0ms; user: 0ms; system: 0ms

Advertisement

Answer

You don’t show any code that deletes the shared memory segment.

If you look at the POSIX specification for shmget(), you will see that the EINVAL error you are reporting can be given if:

[EINVAL]
A shared memory segment is to be created and the value of size is less than the system-imposed minimum or greater than the system-imposed maximum.
[EINVAL]
No shared memory segment is to be created and a shared memory segment exists for key but the size of the segment associated with it is less than size.

I think you may be running into the second case; you’re trying to create a bigger shared memory segment than the one that already exists.

  • Modify your code to clean up behind itself (shmdt(), shmctl()).
  • Use ipcrm to remove the existing shared memory segment.

Also, as I noted in a comment, you should make sure that the client and server programs agree on the size of the structure in shared memory. Anything else is a recipe for disaster. You should put the structure definition into a header, and both your programs should use that header, and both should be recompiled when you change the definition of the header.

Advertisement