将map <string,int =“”>转换为void *并返回并获取键

时间:2017-10-30 15:05:31

标签: c++ c++11 pointers void-pointers

我正在尝试使用void *投射到reinterpret_cast的地图指针,然后使用static_cast

将其强制转换回来

现在,在将void *投回map<string, int> *

之后尝试获取存储在地图中的值时遇到问题

我尝试了基于范围的循环和迭代器,但我似乎无法找到获取密钥的方法,每次我尝试访问地图值时都会出现分段错误。

这是我所拥有的代码的一个小例子:

auto *map_pointer = new map<string, int>;

for (const auto &entry : array){
    if (map_pointer->find(entry) == map_pointer->end()) {
        map_pointer->at(entry) = 1;
    } else {
        map_pointer->at(entry)++;
    }
}

void *test = reinterpret_cast<void *>(map_pointer);
auto foo = static_cast<std::map<std::string, int> *>(test);

如果可能的话,我需要找到一种方法来检索地图的键,以便从中获取值 现在我不知道导致分段错误的问题是否在转换为void *并返回,或者当我试图通过迭代器或循环获取密钥时发生错误。

3 个答案:

答案 0 :(得分:2)

  • 关于指针演员 - 正如StoryTeller指出的那样 - 您可以在需要时将地图指针分配给void*static_cast
  • 关于段错误,您拨打at以获取地图中找不到的密钥,这会导致std::out_of_range

您更正的代码可能如下所示:

std::map<int, int> m = {{0, 8}, {1, 9}, {2, 32}};
std::vector<int> arr = {0, 3, 2};

for (const auto &entry : arr){
    if (m.find(entry) == m.end()) {
        m.insert({entry, 1});
    } else {
        m[entry]++;
    }
}    

void *mp = &m;    
std::map<int, int> *m2 = static_cast<std::map<int, int>*>(mp);

for (const auto& i : *m2) {
    std::cout << i.first << ":" << i.second << "\n";
}

打印0:9 1:9 2:33 3:1。见demo on coliru

答案 1 :(得分:2)

我的经验法则是:

  • 使用static_cast进行投射时,请使用static_cast
  • 进行投射
  • 使用reinterpret_cast进行投射时,请使用reinterpret_cast
  • 进行投射
  • 如果您计划投射值然后使用投放值,请使用reinterpret_cast
  • 如果转换是众所周知/琐碎的转换,例如std::string{"Hello, world"}
  • ,则可以使用C或ctor样式的强制转换

在这里应用,我说&#34;两种方式使用reinterpret_cast&#34;。

答案 2 :(得分:1)

为了避免在条目不存在时抛出异常,正确的循环代码为:

for (const auto &entry : array){
    ++(*map_pointer)[entry];
}

您确定您不仅仅看到导致abort()的未处理异常吗?