首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将multimap转换为空指针,然后再转换回multimap

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

Stack Overflow用户
提问于 2019-10-11 20:55:53
回答 2查看 142关注 0票数 3

我需要将multimap转换为一个空缓冲区,并将其传递给一个函数,在该函数中应该重新构造multimap。

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

代码语言:javascript
复制
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);

}

提前谢谢你!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-10-11 21:35:57

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

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

我让自己对它进行编码:

代码语言:javascript
复制
#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() );        
}
票数 1
EN

Stack Overflow用户

发布于 2019-10-11 21:00:42

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

代码语言:javascript
复制
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 *

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58341732

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档