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
As noted above your code is missing error checking. For example the way for shmat to indicate an error is to return -1, which when it is displayed as a pointer looks like a long int - so that very well what is happening here.
Specifically, note that ftok(), which stand for File Token, needs to get the path to a valid file on the Linux file system to derive the shared memory ID from the file inode number (it does not look at the file content). Unless you have a file in your current directory called SomeString this is why this call is failing.
Last but not least, I really recommend using POSIX shared memory API rather then the SySV API you are using. See shm_open(3) (http://linux.die.net/man/3/shm_open) for the details
The right way to do shared memory in modern programs is with
mmap
andMAP_SHARED
. You can use either an ordinary file or a named shared memory object created withshm_open
.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 inshmget
in that case. Please useperror
to check your error message. Use can try the following codeThe 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:
This also explains why you are getting an ENOENT (No such file or directory) error from ftok.