提问人:Cristian Tamblay 提问时间:10/9/2021 更新时间:10/10/2021 访问量:261
std::map<int,struct> 中的结构体内存泄漏?
Structs in std::map<int,struct> memory leaking?
问:
我有以下结构和映射
struct dataStruct{
unsigned long time;
int32_t ch0;
int32_t ch1;
uint8_t state;
int16_t temp;
uint16_t vbat;
int8_t rssi;
};
std::map<uint32_t,struct dataStruct> uuidData = {};
还有一个循环,它等待新数据并用它填充地图。(1)
for(;;)
{
if (data_debug.is_new_data_available())
{
uint32_t uuid = data_debug.get_ID();
uuidData[uuid] = {
millis(),
data_debug.get_data1(),
data_debug.get_data2(),
data_debug.get_state(),
data_debug.get_temperature(),
data_debug.get_battery_level(),
data_debug.get_RSSI()
};
}
}
这有效,但是当我使用现有 UUID 获取数据时,我的直觉是旧结构永远不会被删除,最终会泄漏。
我在下面有一个替代代码 (2) 试图绕过它,但是当 UUID 被复制时,结构被垃圾填满了。 (1) 中的代码是泄漏还是 c++ 在不再需要结构时自动释放空间?(我知道这听起来像是垃圾回收,但我不知道 c++ 如何处理结构)
(2)
if(uuidData.count(uuid)){
uuidData[uuid].time = millis();
uuidData[uuid].ch0 = data_debug.get_data1();
uuidData[uuid].ch1 = data_debug.get_data2();
uuidData[uuid].state = data_debug.get_state();
uuidData[uuid].temp = data_debug.get_temperature();
uuidData[uuid].vbat = data_debug.get_battery_level();
uuidData[uuid].time = data_debug.get_RSSI();
}
else{
uuidData[uuid] = {
millis(),
data_debug.get_data1(),
data_debug.get_data2(),
data_debug.get_state(),
data_debug.get_temperature(),
data_debug.get_battery_level(),
data_debug.get_RSSI()
};
}
答:
2赞
user4581301
10/9/2021
#1
让我们分解一下示例 1 会发生什么(执行此任务的正确方法)
uuidData[uuid] = {
millis(),
data_debug.get_data1(),
data_debug.get_data2(),
data_debug.get_state(),
data_debug.get_temperature(),
data_debug.get_battery_level(),
data_debug.get_RSSI()
};
这
{
millis(),
data_debug.get_data1(),
data_debug.get_data2(),
data_debug.get_state(),
data_debug.get_temperature(),
data_debug.get_battery_level(),
data_debug.get_RSSI()
};
创建并初始化一个临时变量,这是一个自动变量,只有在不再需要它之前才会存在。当表达式结束时,临时将超出范围并被销毁。dataStruct
uuidData[uuid]
查找匹配的密钥。如果找不到,则创建一个空键并将其映射到键。此新功能由 管理。它从哪里来,到哪里去不是你关心的。一旦映射到存在,就会返回对它的引用。uuidData
uuid
dataStruct
dataStruct
uuidData
dataStruct
uuid
现在,我们参考了地图中的现有和临时的.只需将右侧临时的内容复制到左侧引用所表示的对象中即可。左侧对象中的任何内容都会被覆盖,但该对象仍然存在,并且仍由 管理。当它从范围中删除或超出范围时,它将被正确销毁和解除分配。当表达式完成时,临时变量会自动销毁(因此名称为自动变量)。dataStruct
dataStruct
=
uuidData
uuidData
uuidData
这里没有泄漏的可能性。
评论
uuid
uuidData[uuid] = { ... };
{ ... }
map
map
uuid
delete
new
new
delete
std::map<uint32_t,struct dataStruct>
std::map<uint32_t, dataStruct>