I have the following struct and map
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 = {};
And a loop which waits for new data and fills the map with it. (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()
};
}
}
This works, but when I get data with an existing UUID, my intuition is that the old struct never gets deleted and will eventually leak.
I had an alternative code (2) below that tried to bypass this, but when the UUID was duplicated, the struct was filled with garbage. Is the code in (1) leaking or c automatically frees the space when the struct is no longer needed? (I know this sounds like garbage collection, but i have no idea how c handle structs)
(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()
};
}
CodePudding user response:
Let's break down what happens with example 1 (the correct way to do this task )
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()
};
The
{
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()
};
creates and initializes a temporary dataStruct
variable, an automatic variable that will only exist until it's no longer needed. When the statement ends, the temporary goes out of scope and is destroyed.
uuidData[uuid]
Looks in uuidData
for a key that matches uuid
. If it does not find one, it creates an empty dataStruct
and maps it to the key. This new dataStruct
is managed by uuidData
. Where it comes from and where it goes is none of your concern. Once a dataStruct
mapped to uuid
exists, a reference to it is returned.
Now we have a reference to an existing dataStruct
in the map and the temporary dataStruct
the =
simply copies the contents of the temporary on the right into the the object represented by the reference on the left. Whatever was in the object on the left is overwritten but the object is still there and still managed by uuidData
. It will be properly destroyed and deallocated when it is either removed from uuidData
or uuidData
goes out of scope. The temporary is destroyed automatically (ergo the name Automatic variable) for you when the statement ends.
There is no possibility for a leak here.