Skip to content
Advertisement

Storing and accessing an array of struct from shared memory

I am writing a program on a hotel reservation system and have declared a struct Room as follows:

struct Room {
bool isavailable;
bool ispaid;
string customer;
string date;
};

I use a variable read from an input file to create an array of n structs which is all the rooms in the hotel.

struct Room* rooms = new Room[numOfRooms];

I then create the shared memory space and attach it, but when I try to access it after, it doesn’t seem to work.

//creates shared memory space
if((shmid = shmget(shmkey, 1000, IPC_CREAT | 0666)) < 0) {
    perror("Failed to allocate shared mem");
    exit(1);
}

//attaches shared memory to process
Room* shared_memory;
shared_memory = (Room* ) shmat(shmid, NULL, 0);
if(!shared_memory) {
    perror("Error attaching");
    exit(0);
}

struct Room *PTR = rooms; //temp pointer to rooms array
cout << "test: " << rooms[1].customer << endl; //print before storing in shared memory
rooms = (struct Room*) shared_memory+sizeof(int); //places rooms array in shared memory
delete [] PTR; //deletes the memory location where rooms was stored before being in shared memory
cout << "test: " << rooms[1].customer << endl; //print after storing in shared mem

As you can see I have a cout statement before moving rooms into shared memory which prints the correct thing, but the after cout is empty. Any help would be greatly appreciated, thanks.

Advertisement

Answer

rooms = (struct Room*) shared_memory+sizeof(int); //places rooms array in shared memory

This line does not do what your comment says. First, shared_memory is already declared as Room* shared_memory so the cast is unnecessary. Adding sizeof(int) (let’s assume that is 4) to a pointer will make the pointer point to the 4th such element, that is if shared_memory was pointing to the first element of a Room arr[N] array, the expression shared_memory + i is equal to &arr[i]. In this case, shared_memory+sizeof(int) is a pointer to the 4th (or sizeof(int)‘th) element — or rather where that element would be in the shared_memory because you just created the shared memory and haven’t put any actual Rooms in there yet.

Finally, rooms = ... just assigns a value to the pointer. So now the rooms variable (which is a pointer, just a number basically) points to the place where the 4th Room object in the shared_memory array would be. It’s not copying the array created with new Room[numOfRooms] or anything like that.

See also: How do pointer to pointers work in C?

What you want to do is copy the objects into shared memory. For that in general you could use std::copy like so:

std::copy(&rooms[0], &rooms[numOfRooms], shared_memory);

But the problem will be that std::string contains a pointer to a char array which you can assume to be allocated with new char[length_of_string]. (This is a simplified version of the truth, but enough for this.) The std::copy above will not move this internal array into shared memory, therefore it will not work if you map the shared memory in another process and access the string data. (You might read memory garbage or you might segfault when trying to access unmapped memory.) To solve this, you need to use an allocator type that can allocate from the shared memory, or store strings inline with something like a struct ShortString{ char data[/*max length*/ 20]; }. You’ll want to search for or post another question if you need help with that.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement