Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding Shared Memory Using C

Tags:

c

linux

memory

ftok

Using C, I'm trying to set up shared memory. My code looks like:

key_t key = ftok("SomeString", 1);
static int *sharedval;
int shmid = shmget(key, sizeof(int), S_IRUSR | S_IWUSR); // less permissions
sharedval = (int *) shmat(shmid, NULL, 0);
*sharedval = 0;

However the second I run that last line, I get a segmentation fault. When debugging, I can print "sharedval" and I get a memory address, presumably the place in memory I got. So I would assume all I have to do is use *sharedval to assess it, but apparently not. How am I supposed to read from the shared memory? A push in the right direction would be wonderful. Thanks!

Edit:

another.anon.coward's output:

$ ./a.out 
ftok: No such file or directory
shmget: No such file or directory
Trying shmget with IPC_CREAT
shmget success
shmat success
Segmentation fault: 11
like image 816
adammenges Avatar asked Dec 17 '22 09:12

adammenges


2 Answers

The problem in your case could be that there is no associated memory segment for the given key. You need to create a memory segment by passing IPC_CREAT flag in shmget in that case. Please use perror to check your error message. Use can try the following code

    #include <stdio.h> //For perror
    ...

    key_t key = ftok("SomeString", 1);
    if ( 0 > key )
    {
       perror("ftok"); /*Displays the error message*/
       /*Error handling. Return with some error code*/
    }
    else /* This is not needed, just for success message*/
    {
       printf("ftok success\n");
    }

    static int *sharedval;
    int shmid = shmget(key, sizeof(int), S_IRUSR | S_IWUSR | IPC_CREAT);
    if ( 0 > shmid )
    {
        perror("shmget"); /*Displays the error message*/
    }
    else /* This is not needed, just for success message*/
    {
       printf("shmget success\n");
    }

    sharedval = (int *) shmat(shmid, NULL, 0);
    if ( 0 > sharedval )
    {
       perror("shmat"); /*Displays the error message*/
       /*Error handling. Return with some error code*/
    }
    else /* This is not needed, just for success message*/
    {
       printf("shmat success\n");
    }
    *sharedval = 0;
    ...
like image 181
another.anon.coward Avatar answered Dec 24 '22 01:12

another.anon.coward


The problem is that ftok requires an existing file which can be passed to fstat and not an arbitrary string. From the man page:

key_t ftok(const char* pathname, int proj_id)

The ftok() function uses the identity of the file named by the given pathname (which must refer to an existing, accessible file) ...

An easy fix is to try:

int main(int argc, char* argv[])
{
  key_t key = ftok(argv[0], 1);
  ...
}

This also explains why you are getting an ENOENT (No such file or directory) error from ftok.

like image 30
Barnaby Dalton Avatar answered Dec 24 '22 01:12

Barnaby Dalton