std::unordered_map<int32_t, int32_t> 在堆上声明
Posted
技术标签:
【中文标题】std::unordered_map<int32_t, int32_t> 在堆上声明【英文标题】:std::unordered_map<int32_t, int32_t> declared on heap 【发布时间】:2016-11-29 06:49:49 【问题描述】:在堆上声明一个std::unordered_map,对其执行一些操作,然后释放它的语法是什么?我在做:
std::unordered_map<int32_t, int32_t> *map_temp_last_close = new std::unordered_map<int32_t, int32_t>;
*(map_temp_last_close[val]) = *(int32_t*)(read_buffer + 30); //this happens multiple times in a loop
int32_t some_val = val * (*(map_temp_last_close[val]))
map_temp_last_close->clear();
delete(map_temp_last_close);
编辑:
为什么我需要把它放在堆上?我有一个始终运行的函数,它不断地从网络接收数据,在某些情况下,将数据存储在地图中以进行处理。一旦地图的使用结束,我知道我不会在我的协议中再次收到该消息,因此不需要地图,但地图并没有超出范围,因为函数处于无限循环中(阻塞时网络阅读)。所以我想通过调用free
或delete
或其他方式来释放内存。
【问题讨论】:
为什么需要在堆中这样做?为什么不在堆栈中? @SergeRoussak 查看编辑。 @user2635088:本地堆栈变量(正式地,具有自动存储持续时间的本地变量)在封闭范围的末尾被销毁,它可以小于函数。使用
在函数内创建范围。或者,就像您已经在做的那样,在map
上调用clear()
,这将恢复重要的资源(sizeof (unordered_map)
可以忽略不计,相关的堆数据可能大到足以引起关注,并且clear()
应该注意这一点)。
你是说,你是从另一个线程中删除地图吗?如果是这样,您应该非常小心 - 确保您在两个线程之间使用了同步原语。
@BenVoigt 明白了。我认为clear
应该这样做。谢谢
【参考方案1】:
您的错误是大括号的定位。您必须首先取消引用,然后索引到数据结构中。
我也不会把它放在堆上,因为std::unordered_map
已经在内部将它的数据存储在堆上,但是如果你真的需要,我能想到的最简单和最安全的方法是:
auto map_temp_last_close = std::make_unique<std::unordered_map<int32_t, int32_t>>()
(*map_temp_last_close)[val] = *(int32_t*)(read_buffer + 30);
int32_t some_val = val * (*map_temp_last_close)[val];
//map object will get destroyed automatically when map_temp_last_close goes out of scope, but if you want to delete it earlier, you can use:
map_temp_last_close.reset();
这会在堆上创建一个std::unordered_map
和一个管理它的本地unique_ptr
变量:每当map_temp_last_close
超出范围(无论是通过返回、异常还是仅仅因为当前范围结束),它都会自动删除地图。此外,没有理由在销毁之前调用clear
,因为地图会自动执行此操作。
注意:
很可能(取决于 read_buffer
的类型)这个表达式:*(int32_t*)(read_buffer + 30)
是未定义的行为。
【讨论】:
谢谢。所以read_buffer
是我在调用recv
时从网络接收字节时填充的字符数组。如果网络协议规定在那个位置会有一个 int32_t,这仍然是未定义的行为吗?我知道如果我读取的int32_t
值超出了一定范围,那么协议中有错误,我可以相应地处理该行为
@user2635088: 是的,它在两个方面是未定义的行为,首先是违反严格别名,其次是违反对齐(@987654332@ 不是sizeof (int32_t)
的倍数)。请改用memcpy(&some_val, read_buffer+30, 4)
来获取值。如果您有一个允许错位的平台,编译器将生成一个 32 位移动,每一位都与原始移动一样有效,但行为在形式上是明确定义的。在对齐很重要的平台上,您将获得工作代码。
@BenVoigt 我可以使用memcpy
复制到 (*map_temp_last_close)[val] 吗?会是memcpy(&((*map_temp_last_close)[val]), read_buffer+30, 4);
吗?
@user2635088:是的,你可以,对于std::unordered_map
和operator[]
返回T&
的任何其他集合。只是不要尝试使用std::vector<bool>
以上是关于std::unordered_map<int32_t, int32_t> 在堆上声明的主要内容,如果未能解决你的问题,请参考以下文章
为啥我不能增加 std::unordered_map 迭代器?
Javascript中C++ std::unordered_map<char, int> 的等价物是啥?
std::unordered_map::clear() 做啥?