将 multimap 转换为 void 指针,然后再转换回 multimap

Convert multimap to void pointer and then back to multimap

我需要将 multimap 转换为 void 缓冲区,并将其传递给应该重建 multimap 的函数。

我知道有简单的方法可以简单地传递多图,但我需要通过 void 指针来做,所以请看下面我的逻辑:

using namespace std;

void reconstruct_mm(void *ptr, size_t len) {

    multimap<int, int> *mm = ptr;
    mm = (multimap<<int, int>*>malloc(len));

    *** print the following 10, 20, 30...

}

int main (void) {

    void *buffer;
    size_t buffer_len = 0;

    multimap <int, int> m;

    // fill in multimap with values
    m.insert(pair <int, int> (1, 10);
    m.insert(pair <int, int> (2, 20);
    m.insert(pair <int, int> (3, 30);

    // from this point I need your help, I only wrote logic what I expect from the program.

    buffer = &mm;
    buffer_len = sizeof(mm);

    reconstruct_mm(buffer, buffer_len);

}

提前致谢!

从技术上讲,您可以只使用 static_cast,根本不需要任何内存分配:

void reconstruct_mm(void *ptr/* Next argument unneeded:, size_t len*/) {

   multimap<int, int> *mm = static_cast<multimap<int, int> *>(ptr);

   // Use here mm as a multimap pointer regularly
   cout << mm->size() << '\n';

}

我能想到的唯一合法的情况是,如果您受某些遗留代码的约束,例如,需要诸如带有 void * 接口的回调之类的代码。如果不是这种情况,请考虑避免使用 void * 开头。

如果您需要从 void* 克隆 reconstruct_mm() 函数内的地图,则无法直接完成,因为 std::map / std::multimap 是非线性关联容器及其元素分布在堆内存的不同部分(加上它在堆栈上的直接对象)。

您必须编写某种序列化和反序列化例程。序列化将是一个循环,它逐个键读取映射键并将后续键及其值存储在分配的内存缓冲区中。然后你可以通过 void* 将它传递给 reconstruct_mm() 并且在另一侧你做完全相反的事情(反序列化)遍历缓冲区并将键和值插入到新映射中。

我让自己编码:

#include <map>
#include <memory>
#include <iostream>

void reconstruct_mm(void *ptr, size_t len)
{
    std::multimap<int, int> m;
    int* buffer {static_cast<int*>(ptr)};    

    for (int i {0}; i < len*2; i+=2)
    {        
        m.insert( std::pair<int, int>(buffer[i], buffer[i+1]) );
    }

    for (auto const & elem : m) //check the values
    {
        std::cout << elem.first << " " << elem.second << std::endl;
    }
}

int main(void)
{
    std::multimap <int, int> m;

    // fill in multimap with values
    m.insert( std::pair<int, int>(1, 10) );
    m.insert( std::pair<int, int>(2, 20) );
    m.insert( std::pair<int, int>(3, 30) );

    //smart pointer to release buffer's memory at the end (credits: Paul McKenzie)
    auto buffer {std::make_unique<int[]>(m.size()*2)}; //*2 - for key int + value int 

    int i {0};
    for (auto const & elem : m)
    {
        buffer[i++] = elem.first;
        buffer[i++] = elem.second;
    }    

    reconstruct_mm( static_cast<void*>(buffer.get()), m.size() );        
}