将 map<string, int> 转换为 void* 并返回并获取密钥
convert map<string, int> to void* and back and get keys
我正在尝试使用 reinterpret_cast
将映射指针投射到 void *
,然后使用 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 *
并返回时还是在我尝试使用迭代器或循环取回密钥时发生错误。
- 关于指针转换 - 正如 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
我的经验法则是:
- 当你用
static_cast
施放时,用 static_cast
施放
- 当你用
reinterpret_cast
施放时,用 reinterpret_cast
施放
- 如果您打算转换一个值然后使用转换后的值,请不要使用
reinterpret_cast
- 当转换是 well-known/trivial 时,使用 C 或 ctor 风格的转换是可以接受的,例如
std::string{"Hello, world"}
在这里申请,我会说"use reinterpret_cast both ways"。
为避免条目不存在时抛出异常,正确的循环代码是这样的:
for (const auto &entry : array){
++(*map_pointer)[entry];
}
您确定您看到的不仅仅是导致 abort()
的未处理异常吗?
我正在尝试使用 reinterpret_cast
将映射指针投射到 void *
,然后使用 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 *
并返回时还是在我尝试使用迭代器或循环取回密钥时发生错误。
- 关于指针转换 - 正如 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
我的经验法则是:
- 当你用
static_cast
施放时,用static_cast
施放
- 当你用
reinterpret_cast
施放时,用reinterpret_cast
施放
- 如果您打算转换一个值然后使用转换后的值,请不要使用
reinterpret_cast
- 当转换是 well-known/trivial 时,使用 C 或 ctor 风格的转换是可以接受的,例如
std::string{"Hello, world"}
在这里申请,我会说"use reinterpret_cast both ways"。
为避免条目不存在时抛出异常,正确的循环代码是这样的:
for (const auto &entry : array){
++(*map_pointer)[entry];
}
您确定您看到的不仅仅是导致 abort()
的未处理异常吗?