从共享内存存储和访问结构数组
Storing and accessing an array of struct from shared memory
我正在写一个关于酒店预订系统的程序,并声明了一个 struct Room 如下:
struct Room {
bool isavailable;
bool ispaid;
string customer;
string date;
};
我使用从输入文件中读取的变量来创建一个包含 n 个结构的数组,它是酒店的所有房间。
struct Room* rooms = new Room[numOfRooms];
然后我创建共享内存 space 并附加它,但是当我之后尝试访问它时,它似乎不起作用。
//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 语句,它打印出正确的内容,但之后的 cout 是空的。非常感谢任何帮助,谢谢。
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
变量(这是一个指针,基本上只是一个数字)指向 shared_memory
数组中第 4 个 Room
对象所在的位置。它不会复制使用 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]; }
之类的内联存储字符串.如果需要帮助,您可以搜索或 post 另一个问题。
我正在写一个关于酒店预订系统的程序,并声明了一个 struct Room 如下:
struct Room {
bool isavailable;
bool ispaid;
string customer;
string date;
};
我使用从输入文件中读取的变量来创建一个包含 n 个结构的数组,它是酒店的所有房间。
struct Room* rooms = new Room[numOfRooms];
然后我创建共享内存 space 并附加它,但是当我之后尝试访问它时,它似乎不起作用。
//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 语句,它打印出正确的内容,但之后的 cout 是空的。非常感谢任何帮助,谢谢。
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
变量(这是一个指针,基本上只是一个数字)指向 shared_memory
数组中第 4 个 Room
对象所在的位置。它不会复制使用 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]; }
之类的内联存储字符串.如果需要帮助,您可以搜索或 post 另一个问题。