我需要将multimap转换为一个空缓冲区,并将其传递给一个函数,在该函数中应该重新构造multimap。
我知道有一种简单的方法可以简单地传递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);
}提前谢谢你!
发布于 2019-10-11 21:35:57
如果需要从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() );
}发布于 2019-10-11 21:00:42
从技术上讲,您可以只使用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 *。
https://stackoverflow.com/questions/58341732
复制相似问题