从共享内存存储和访问结构数组 [英] Storing and accessing an array of struct from shared memory

查看:90
本文介绍了从共享内存存储和访问结构数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在酒店预订系统上编写一个程序,并声明了一个房间结构如下:

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;
};

我使用从输入文件中读取的变量来创建一个包含 n 个结构体的数组,该数组包含酒店中的所有房间.

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

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

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.

推荐答案

rooms = (struct Room*) shared_memory+sizeof(int);//将房间数组放在共享内存中

此行与您的评论所说的不符.首先,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)'th)元素的指针——或者更确切地说,该元素所在的位置shared_memory 因为你刚刚创建了共享内存,还没有把任何实际的 Room 放在那里.

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.

最后,rooms = ... 只是为指针赋值.所以现在 rooms 变量(它是一个指针,基本上只是一个数字)指向 shared_memory 数组中第 4 个 Room 对象所在的位置将会.它不会复制使用 new Room[numOfRooms] 或类似内容创建的数组.

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.

另见:指向指针的指针在 C 中如何工作?

您要做的是将对象复制到共享内存中.为此,通常您可以使用 std::copy 像这样:

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);

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

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.

这篇关于从共享内存存储和访问结构数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆