In software provided for multiple system on a chip microcontrollers I discovered this piece of code
String getMacAddress() {
uint8_t baseMac[6];
char baseMacChr[13] = {0};
# if defined(ESP8266)
WiFi.macAddress(baseMac);
sprintf(baseMacChr, "XXXXXX", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
# elif defined(ESP32)
esp_read_mac(baseMac, ESP_MAC_WIFI_STA);
sprintf(baseMacChr, "XXXXXX", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
# else
sprintf(baseMacChr, "XXXXXX", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
# endif
return String(baseMacChr);
}
Where String
is provided by Arduino context. So on those microcontroller is this piece of code safe?
I know that there is a problem with the scope/longevity of the returned variable (well explained here: Returning a C string from a function ) which most people get around with the std::string
but I don't have any experience in the context of microcontrollers, and since I've seen it used a lot, I've come up with this question.
I haven't found any documentation about it, every bit of extra information is welcome.
CodePudding user response:
The String class in arduino does not store a pointer to a character but copies it into its internal memory.
The copy constructor takes care of the rest when returning String from a function.
So yes, it's safe
CodePudding user response:
Is it safe returning Arduino String
Yes. String
manages it's memory.
from a C function?
Well, it's not a "C function", it's a normal function in C .
which most people get around with the std::string but I don't have any experience in the context of microcontrollers
It does not differ that much, and you can also use std::string
on esp.
String
and other similar interfaces from Arduino are there to save memory (use realloc
, instead of delete new
on resize) and to interface with Arduino specific stuff easier (constructor with __FlashStringHelper
). It's meant to "mimic" std::string
with some Arduino or embedded specific behavior.
CodePudding user response:
Looks fine to me since you are allocating the strings with automatic storage duration in the caller to the function.
Check they are of sufficient size though - you need to consult the function documentation for that.
With return String(baseMacChr);
, baseMacChr
does not go out of scope conceptually until the closing }
of the function getMacAddress
, so that too is safe.
If you can use std::string
rather than String
then it would be even better. Every C programmer knows exactly what the former is. Using String
(whatever that is) can only add to confusion.