0

I am working on a server with forking which stores a map(k->v) of strings in shared memory. I want to do it very simplistic but am lost in pointers and in what exactly I need to copy. So I extracted the relevant code which looks like this:

struct key_value {
    char key[32];
    char value[32];
};

struct key_value **map;
int *map_size;

int shmid = shmget(IPC_PRIVATE, sizeof(struct key_value**), 0600);
map = (struct key_value**) shmat(shmid, 0, 0);
int shmid_size = shmget(IPC_PRIVATE, sizeof(int), 0600);
map_size = (int*) shmat(shmid_size, 0, 0);
*map_size = 0;
//the above happens before fork()

char *c = "abc";

int shmid_struct = shmget(IPC_PRIVATE, sizeof(struct key_value*), 0600);
struct key_value *entry = (struct key_value*) shmat(shmid_struct, 0, 0);
*entry->key = *c;

printf("%s\n", map[0]->key);

//smhdt's & shmctl's

So what I want is to copy that string "abc" from *c into the map so into shared memory. Clearly, I do not yet fully understand pointers and structs so am hoping someone can clear it up. I currently get a segfault 'somewhere in main' (thanks gdb...).

Note that I am ok with the map having a fixed max_size for now (though would be great if dynamic).

EDIT: it's been pointed out in an answer that having a char* in the struct is difficult, so to use char[x] instead. Have updated the code to reflect that, but still not working.

Dimebag
  • 833
  • 2
  • 9
  • 29

1 Answers1

3

Structures which contain pointers cannot be safely stored in shared memory, as the pointers are meaningless outside the process that created them. Even if the shared memory region is mapped at the same address in each process (which is true if the memory was mapped before a fork(), but may be false in other scenarios), pointers into non-shared memory will not behave properly, as each process may have different data at that address.

If you want to store strings in shared memory, you will need to store them as explicit character arrays, e.g.

struct key_value {
    char key[32];
    char value[32];
};

or use another scheme, such as storing an offset into a string table in the shared memory region.

Generally speaking, though, shared memory is not a good tool for inter-process communication. If your application depends on being able to share data in memory, threading is probably a better approach.

  • My task is as I mentioned: share a map(k->v) between processes on a server. Do you see any simpler solution than using shared memory? I cannot e.g. store things in a file. Furthermore, could you provide a small working example using key[32] in a struct instead? Only changing to [32] does not make my code work so I still need to understand what exactly needs to be copied and how. – Dimebag Sep 26 '17 at 19:12