简体   繁体   English

共享内存中向量的结构

[英]Struct of vectors in Shared Memory

I have following struct: 我有以下结构:

struct outData{   
    int a;
    float lat, lon;
}

which is used for IPC via shared memory. 通过共享内存用于IPC。 Now i want to update it to look something like this: 现在我想更新它看起来像这样:

    struct outData{
        int a;   
        std::vector<std::pair<std::string, int>> allInts;
        std::vector<std::pair<std::string, float>> allfloats;
}

my shared memory is 4096 Bytes big for convienience, so that i don't have to modify a sizeof(outData) line of code every time i make changes to the struct. 为了方便起见,我的共享内存大4096字节,所以每次我对结构进行更改时,我都不必修改sizeof(outData)代码行。

When i create such a struct with dynamic members is it guaranteed that they are all created after the (int a) and therefore in the shared memory? 当我用动态成员创建这样的结构时,是否保证它们都是在(int a)之后创建的,因此在共享内存中创建?

what about vectors of vectors like? 怎么样的矢量矢量?

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

Wow thanks for the fast answers! 哇谢谢快速的答案! Based on your input i worked out this solution: 根据您的输入,我得出了这个解决方案:

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

This works, but it's not very thoroughly tested. 这可行,但它没有经过彻底的测试。 Thank you! 谢谢!

This can't work. 这不行。 The strings won't be in shared memory. 字符串不在共享内存中。 The std::string object will be, but its contents won't be. std::string对象将是,但其内容不会。 The same is true for std::vector<byte> . 对于std::vector<byte>也是如此。 The vector object will be in shared memory, but its contents won't be. vector对象将位于共享内存中,但其内容不会。

Both of these classes have no idea how big their contents will be when they're constructed. 这两个类都不知道它们构造时的内容有多大。 So their static content just includes enough information to find their dynamic content. 因此,他们的静态内容只包含足够的信息来查找其动态内容。 The dynamic content is allocated separately. 动态内容单独分配。

If you're going to use shared memory, you must define the contents of that shared memory at the byte level. 如果要使用共享内存,则必须在字节级别定义该共享内存的内容。 Classes with internal absolute pointers will not work. 具有内部绝对指针的类将不起作用。 If you need pointers, you'll have to make them relative to the start of the shared memory segment so that they're meaningful across processes. 如果需要指针,则必须使它们相对于共享内存段的起点,以便它们在进程间有意义。

I'm not sure what you mean by "is it guaranteed that they are all created after the (int a) and therefore in the shared memory". 我不确定你的意思是“它是否保证它们都是在(int a)之后创建的,因此在共享内存中创建”。

However, I think that you can't use objects with virtual tables (any object with at least one virtual function) in shmem. 但是,我认为你不能在shmem中使用具有虚拟表的对象(任何具有至少一个虚函数的对象)。 This will probably cause a crash when any such function (the destructor, for instance) is called. 当调用任何此类函数(例如析构函数)时,这可能会导致崩溃。

This is in addition to the fact that the memory used by the array is dynamically allocated, ie the actual array is located elsewhere. 这是除了数组使用的内存是动态分配的事实之外,即实际数组位于其他地方。

You probably will need to resort to using a custom structure, something like: 您可能需要使用自定义结构,例如:

struct {
    int arraySize;
    int array[];
}

This is just barely possible, but not worth it. 这几乎是不可能的,但不值得。

The std::string and std::vector classes store data outside of themselves, usually on the heap allocated with new. std :: string和std :: vector类将数据存储在自身之外,通常在使用new分配的堆上。 You can pass a different allocator as a template parameter, in which case that will be used instead of new. 您可以将不同的分配器作为模板参数传递,在这种情况下将使用而不是新的。 You could, in theory, write an allocator that understood your shared memory. 理论上,您可以编写一个了解共享内存的分配器。 Note that writing a reliable allocator is hard. 请注意,编写可靠的分配器很难。

Also, the std structures have internal pointers. 此外,std结构具有内部指针。 If the virtual address of the shared memory is different in the two processes (which is likely) then those pointers will go to strange parts of memory. 如果共享内存的虚拟地址在两个进程(可能是)中不同,那么这些指针将转到内存的奇怪部分。

Note that you can put plain old c-style arrays in structs, and those will do what you want. 请注意,您可以在结构中放置普通的旧C风格数组, 这些数组将执行您想要的操作。 Including, you can use a variable length struct, provided you don't do very c++ish things to it. 包括,你可以使用一个可变长度的结构,前提是你没有做很多c ++的事情。

Probably won't work. 可能不会起作用。

  • As pointed out by @DavidSchwartz the vector will store the actual strings in internally managed memory (which of course doesn't have any respect to whatever proprietary shared memory mechanism you have). 正如@DavidSchwartz指出的那样,向量将实际的字符串存储在内部管理的内存中(当然,这与你拥有的任何专有共享内存机制没有任何关系)。
  • Any non-POD data type normally has a hefty amount of auto-generated code that will be stored at a location that you can't control: virtual table, auto-generated constructors etc. There are ways to control this behavior but it's not trivial, not always possible and not always good enough. 任何非POD数据类型通常都有大量自动生成的代码,这些代码将存储在您无法控制的位置:虚拟表,自动生成的构造函数等。有一些方法可以控制这种行为,但这并不是一件容易的事。 ,并非总是可能,并不总是足够好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM