我有以下结构:
struct outData{
int a;
float lat, lon;
}
通过共享内存用于IPC。现在我想更新它看起来像这样:
struct outData{
int a;
std::vector<std::pair<std::string, int>> allInts;
std::vector<std::pair<std::string, float>> allfloats;
}
为了方便起见,我的共享内存大4096字节,因此每次我对结构进行更改时,我都不必修改sizeof(outData)代码行。
当我使用动态成员创建这样的结构时,是否保证它们都是在(int a)之后创建的,因此在共享内存中创建?
像载体的载体怎么样?
struct outData{
int a;
std::vector<std::pair<std::string, int>> allInts;
std::vector<std::pair<std::string, float>> allfloats;
std::vector<std::pair<std::string, std::vector<byte>>> allByteMessages;
}
哇谢谢快速回答!根据您的输入,我得出了这个解决方案:
struct outData{
int *iarray;
float *farray;
} gtempStruct;
SetSharedMem(std::vector<std::pair<int, float>> &input)
{
void * p_v;
gtempStruct.iarray = new int[input.size()];
gtempStruct.farray = new float[input.size()];
fillStruct(input);
outData *p_oD = (outData *) p_Shm; // p_Shm = pointer to shared memory start
*p_oD = gtempStruct;
p_v = p_oD;
p_v = reinterpret_cast<char*>(p_v) + sizeof(outData) -1;
p_v = reinterpret_cast<void*>(p_v);
memcpy(p_v, gtempStruct.iarray, sizeof(int)*input.size())
p_oD->iarray = (int*) p_v;
.
.
.
}
这有效,但未经过彻底测试。 谢谢!
答案 0 :(得分:2)
这不起作用。字符串不在共享内存中。 std::string
对象将是,但其内容不会。 std::vector<byte>
也是如此。 vector对象将位于共享内存中,但其内容不会是。
这两个类都不知道它们构建时的内容有多大。因此,他们的静态内容只包含足够的信息来查找其动态内容。动态内容是单独分配的。
如果要使用共享内存,则必须在字节级别定义该共享内存的内容。具有内部绝对指针的类将不起作用。如果需要指针,则必须使它们相对于共享内存段的开头,以便它们在进程间有意义。
答案 1 :(得分:1)
我不确定你的意思是“它是否保证它们都是在(int a)之后创建的,因此在共享内存中创建”。
但是,我认为你不能在shmem中使用具有虚拟表的对象(具有至少一个虚函数的任何对象)。当调用任何此类函数(例如析构函数)时,这可能会导致崩溃。
这是因为数组使用的内存是动态分配的,即实际数组位于其他位置。
您可能需要使用自定义结构,例如:
struct {
int arraySize;
int array[];
}
答案 2 :(得分:1)
这几乎是不可能的,但不值得。
std :: string和std :: vector类将数据存储在自身之外,通常在使用new分配的堆上。您可以将不同的分配器作为模板参数传递,在这种情况下将使用而不是新的。理论上,您可以编写一个了解共享内存的分配器。请注意,编写可靠的分配器很难。
此外,std结构有内部指针。如果共享内存的虚拟地址在两个进程中是不同的(很可能),那么这些指针将转到内存的奇怪部分。
请注意,您可以在结构中放置普通的旧式C风格数组,那些将执行您想要的操作。包括,你可以使用一个可变长度的结构,前提是你不要做很多c ++事情。
答案 3 :(得分:0)
可能无效。