C++ 共享内存中的向量结构
我有以下结构:C++ 共享内存中的向量结构,c++,memory,vector,struct,ipc,C++,Memory,Vector,Struct,Ipc,我有以下结构: 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, fl
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字节,因此每次修改结构时,我不必修改sizeofoutData代码行
当我用动态成员创建这样一个结构时,是否保证它们都是在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;
.
.
.
}
这是可行的,但没有经过彻底的测试。
谢谢大家! 这行不通。字符串将不在共享内存中。std::string对象将是,但其内容不会是。std::vector也是如此。矢量对象将在共享内存中,但其内容不会在共享内存中 这两个类都不知道构建时它们的内容会有多大。因此,它们的静态内容只包含足够的信息来查找它们的动态内容。动态内容是单独分配的
如果要使用共享内存,必须在字节级别定义共享内存的内容。带有内部绝对指针的类将无法工作。如果需要指针,则必须使其相对于共享内存段的开头,以便它们在整个进程中都有意义。这不起作用。字符串将不在共享内存中。std::string对象将是,但其内容不会是。std::vector也是如此。矢量对象将在共享内存中,但其内容不会在共享内存中 这两个类都不知道构建时它们的内容会有多大。因此,它们的静态内容只包含足够的信息来查找它们的动态内容。动态内容是单独分配的 如果要使用共享内存,必须在字节级别定义共享内存的内容。带有内部绝对指针的类将无法工作。如果需要指针,则必须使其相对于共享内存段的开头,以便它们在整个进程中都有意义。可能无法工作 正如@DavidSchwartz所指出的,向量将把实际的字符串存储在内部管理的内存中,这当然与您拥有的任何专有共享内存机制无关。 任何非POD数据类型通常都有大量自动生成的代码,这些代码将存储在您无法控制的位置:虚拟表、自动生成的构造函数等。有很多方法可以控制这种行为,但这并不简单,不总是可能的,也不总是足够好的。 可能不行 正如@DavidSchwartz所指出的,向量将把实际的字符串存储在内部管理的内存中,这当然与您拥有的任何专有共享内存机制无关。 任何非POD数据类型通常都有大量自动生成的代码,这些代码将存储在您无法控制的位置:虚拟表、自动生成的构造函数等。有很多方法可以控制这种行为,但这并不简单,不总是可能的,也不总是足够好的。
我不知道你说的是什么意思,它是否保证它们都是在int a之后创建的,因此在共享内存中 但是,我认为不能将对象与虚拟表一起使用,也不能将任何对象与shmem中至少一个虚拟函数一起使用。例如,当调用析构函数时,这可能会导致崩溃 此外,阵列使用的内存是动态分配的,即实际阵列位于其他位置 您可能需要使用自定义结构,例如:
struct {
int arraySize;
int array[];
}
我不知道你说的是什么意思,它是否保证它们都是在int a之后创建的,因此在共享内存中 但是,我认为不能将对象与虚拟表一起使用,也不能将任何对象与shmem中至少一个虚拟函数一起使用。例如,当调用析构函数时,这可能会导致崩溃 此外,阵列使用的内存是动态分配的,即实际阵列位于其他位置 您可能需要使用自定义结构,例如:
struct {
int arraySize;
int array[];
}
这几乎不可能,但不值得 std::string和std::vector类将数据存储在它们自身之外,通常存储在分配了new的堆上。您可以将不同的分配器作为模板参数传递,在这种情况下,将使用它而不是新的。理论上,您可以编写一个能够理解共享内存的分配器。请注意,编写一个可靠的分配器是很困难的 此外,std结构具有内部指针。如果共享内存的虚拟地址在这两个进程中是不同的,那么这两个进程可能是不同的 rs将进入记忆的陌生部分
请注意,您可以在结构中放置普通的旧c样式数组,这些数组将执行您想要的操作。包括,您可以使用一个可变长度的结构,前提是您不需要对它执行非常c++的操作。这几乎不可能,但不值得 std::string和std::vector类将数据存储在它们自身之外,通常存储在分配了new的堆上。您可以将不同的分配器作为模板参数传递,在这种情况下,将使用它而不是新的。理论上,您可以编写一个能够理解共享内存的分配器。请注意,编写一个可靠的分配器是很困难的 此外,std结构具有内部指针。如果共享内存的虚拟地址在两个进程中不同,那么这些指针很可能会指向内存中的奇怪部分
请注意,您可以在结构中放置普通的旧c样式数组,这些数组将执行您想要的操作。包括,您可以使用可变长度的结构,前提是您不需要对其执行非常c++的操作。数据成员的相对位置可以。但是,向量和字符串内部可能有指针。假设您的共享内存在进程之间共享,并且这些进程有不同的地址空间,那么这是不可行的。顺便说一句,如果您还没有这样做,请看一看。谢谢,我假设这不可行。我看了boost.interprocess,但我不想使用boost,因为我想学习这个低级的东西。最终,我的应用程序应该运行在raspberry pi上。塔尔特别的boost库有非常详细的说明文档,所以它可能会给你一些好主意,并向你解释陷阱。顺便说一句,我在Beagleboard上使用过它和其他boost库,没有太多问题。数据成员的相对位置还可以。但是,向量和字符串内部可能有指针。假设您的共享内存在进程之间共享,并且这些进程有不同的地址空间,那么这是不可行的。顺便说一句,如果您还没有这样做,请看一看。谢谢,我假设这不可行。我看了boost.interprocess,但我不想使用boost,因为我想学习这个低级的东西。最终,我的应用程序应该运行在raspberry pi上。塔尔特别的boost库有非常详细的说明文档,所以它可能会给你一些好主意,并向你解释陷阱。顺便说一句,我在Beagleboard上使用过它和其他boost库,没有太多问题。