Ran this code as an experiment and got the following result:
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
float pi = 3.1415926535;
String s = String(pi, 3);
char *p = s.c_str();
Serial.print("p allocated:");
Serial.println(p);
Serial.println(s); //string value OK here
free(p);
Serial.print("p de-allocated:");
Serial.println(p);
Serial.println(s); //string value NOK here. Was 's' deallocated as well??
}
void loop() {
// put your main code here, to run repeatedly:
}
OUTPUT:
p allocated:3.142
3.142
p de-allocated:
142
I would have expected 's' to remain unchanged... why is it not so?
Why are you expecting the memory not to be impacted after that ?
You’ve returned to the heap something that was not for your code to play with (c_str() is a const char * and should be left alone) so the bytes are back to the pool of memory that can be used and there is no implicit warranty that nothing will happen to the bytes you freed up.
Why did you expected that?
Method c_str() returns a pointer to the data inside String. Any modification the data on the pointer will change the String data.
From the String class c_str() reference page:
Converts the contents of a String as a C-style, null-terminated string. Note that this gives direct access to the internal String buffer and should be used with care. In particular, you should never modify the string through the pointer returned.
C++ at least allows that c_str() returns the address of the first character in the String. Freeing such a pointer can/will free the String as well. Example for such aliasing in C:
you are not even sure (unless you read the String class source code) that the pointer you got was the one obtained by malloc/realloc and in any case any further operations which dereference the pointer is undefined behaviour and and thus anything can happen.
My idea as well. But flash and RAM have almost different addressing modes and pointer types in Harvard architecture. So string literals are usually copied into RAM when assigned to a (non-const) pointer.