将 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() );
}
我需要将 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() );
}