从共享内存中存储和访问结构数组

时间:2018-11-13 08:38:37

标签: c++ linux unix shared-memory

我正在酒店预订系统上编写程序,并声明了一个struct Room,如下所示:

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

我使用从输入文件读取的变量来创建n个结构的数组,这是酒店的所有房间。

struct Room* rooms = new Room[numOfRooms];

然后我创建共享内存空间并附加它,但是当我尝试访问它之后,它似乎不起作用。

//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

如您所见,在将房间移到共享内存之前,我有一个cout语句,该语句可以打印正确的内容,但是after cout为空。任何帮助将不胜感激,谢谢。

1 个答案:

答案 0 :(得分:1)

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

此行不执行您的评论所说的。首先,shared_memory已被声明为Room* shared_memory,因此不需要强制转换。向指针添加sizeof(int)(假设为4)将使指针指向第4个此类元素,也就是说,如果shared_memory指向Room arr[N]数组的第一个元素,表达式shared_memory + i等于&arr[i]。在这种情况下,shared_memory+sizeof(int)是指向第4个(或第sizeof(int)个)元素的指针-或更确切地说,该元素在shared_memory中的位置,因为您刚刚创建了共享内存并尚未在其中放置任何实际的Room

最后,rooms = ...只是为指针分配了一个值。因此,现在rooms变量(它是一个指针,基本上只是一个数字)指向Room数组中第四个shared_memory对象所在的位置。它不是在复制用new Room[numOfRooms]或类似方法创建的数组。

另请参阅:How do pointer to pointers work in C?

您要执行的操作是将对象复制到共享内存中。为此,通常可以这样使用std::copy

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

但是问题是std::string包含一个指向char数组的指针,您可以假定它与new char[length_of_string]一起分配。 (这是事实的简化版本,但这已足够。)上面的std::copy不会将此内部数组移动到共享内存中,因此,如果您映射共享的,它将不起作用在另一个进程中存储并访问字符串数据。 (您可能会在尝试访问未映射的内存时读取内存垃圾,或者可能遇到段错误。)要解决此问题,您需要使用可以从共享内存中分配的分配器类型,或使用struct ShortString{ char data[/*max length*/ 20]; }之类的内联存储字符串。如果您需要帮助,则需要搜索或发布其他问题。