While Edgar was writing some test code, so was I. :)
#include <memdebug.h>
String foo;
String f() {
String s = String("");
s += "a"; // ...
s += "bc"; // ...
return s;
} // end of f
void showMemoryUsage ()
{
Serial.println (F("---------------"));
Serial.print (F("Largest block in freelist: "));
Serial.println (getLargestBlockInFreeList ());
Serial.print (F("Largest available memory: "));
Serial.println (getLargestAvailableMemoryBlock ());
Serial.print (F("Free memory: "));
Serial.println (getFreeMemory ());
Serial.print (F("address of foo data = "));
Serial.println ((int) foo.c_str ());
} // end of showMemoryUsage
void setup()
{
Serial.begin (115200);
Serial.println ();
showMemoryUsage ();
Serial.println (F("Calling f() ..."));
foo = f ();
showMemoryUsage ();
Serial.println (F("Calling f() ..."));
foo = f ();
showMemoryUsage ();
Serial.print (F("foo = "));
Serial.println (foo);
} // end of setup
void loop ()
{
} // end of loop
Memory debug library from http://andybrown.me.uk/wk/2011/01/01/debugging-avr-dynamic-memory-allocation/
Output:
---------------
Largest block in freelist: 0
Largest available memory: 1675
Free memory: 1677
address of foo data = 478
Calling f() ...
---------------
Largest block in freelist: 2
Largest available memory: 1669
Free memory: 1675
address of foo data = 482
Calling f() ...
---------------
Largest block in freelist: 2
Largest available memory: 1669
Free memory: 1675
address of foo data = 482
foo = abc
The address of the data in foo has changed from 478 to 482, so my prediction above was right. The function f() made a String, but a second copy was returned, hence we have now "lost" 4 bytes in the heap. Well, not lost, but there is a gap.
Calling f() a second time did not make the fragmentation worse.
BTW, this is unnecessary:
String s = String("");
Just write:
String s;
You are invoking a second String just to provide something to copy into the first String. Strings start off empty so this is just wasted time.