marcioggs
marcioggs

Reputation: 687

Error when trying to attach an used address of shared-memory

Receiving the message "Invalid argument" when using shmget with the second parameter not being NULL.

It compiles ok, but when executing, I get this error message.

I've been stuck on this all day long. Hope you can help me! :)

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


int main()
{
    int idSharedMem;
    int *varSharedMem1;
    int *varSharedMem2;

    /* Create the shared memory */
    idSharedMem = shmget((key_t) 0001, sizeof(int), IPC_CREAT | 0666);

    if (idSharedMem == -1)
    {
        perror("shmget");
    }

    /* Allocate a memory address and attached it to a variable */
    varSharedMem1 = shmat(idSharedMem, NULL, 0);

    if (varSharedMem1 == (int *) -1)
    {
        perror("shmat1");
    }

    /* Sign a value to the variable */
    *varSharedMem1 = 5;

    /* Attach an existing allocated memory to another variable */
    varSharedMem2 = shmat(idSharedMem, varSharedMem1, 0);

    if (varSharedMem2 == (int *) -1)
    {
        /* PRINTS "shmat2: Invalid argument" */
        perror("shmat2");
    }

    /* Wanted it to print 5 */
    printf("Recovered value %d\n", *varSharedMem2);

    return(0);
}

Upvotes: 3

Views: 3615

Answers (2)

nos
nos

Reputation: 229058

With shmat(idSharedMem, varSharedMem1, 0); you're trying to attach the segment at the location of varSharedMem1. However you have previously attached a segment at that location which will result in EINVAL. Linux provides a SHM_REMAP flag you can use to replace previously mapped segments.

shmat manpage:

The (Linux-specific) SHM_REMAP flag may be specified in shmflg to indicate that the mapping of the segment should replace any existing mapping in the range starting at shmaddr and continuing for the size of the segment. (Normally an EINVAL error would result if a mapping already exists in this address range.) In this case, shmaddr must not be NULL.

Upvotes: 4

Tio Pepe
Tio Pepe

Reputation: 3089

From shmat man page:

If shmaddr isn't NULL and SHM_RND is specified in shmflg, the attach occurs at the
address equal to shmaddr rounded  down  to  the nearest multiple of SHMLBA. 
Otherwise shmaddr must be a page-aligned address at which the attach occurs.

more from shmat man page:

Using shmat() with shmaddr equal to NULL is the preferred, portable way of 
attaching a shared memory segment.

To make a second attach, just:

varSharedMem2 = shmat(idSharedMem, NULL, 0);

Upvotes: 1

Related Questions