String += not working

Hi,

could someone please test this code on his arduino. It hangs on mine (Arduino Mega2560 R2).

void setup() { 
  Serial.begin(9600);
}

void loop() { 

  const String args[3] = {
    "foo", "boo", "baa"    };
  String result = "";
  Serial.println(result);
  result += args[0];
  Serial.println(result);
  result += args[1];
  Serial.println(result);
  result += args[2];
  Serial.println(result);
  Serial.println();
}

That codes hangs after a few seconds. BUT if you replace the result += with result = result +

everything works fine. I wonder, as http://arduino.cc/en/Tutorial/StringAppendOperator shows that using += ist OK

regards Mirko

I tried a few more string-things and had strange results. Can someone confirm that code below, or is that a problem of my arduino?
(Uncomment only one of the lines in the source)

void setup ()
{
  Serial.begin(9600);
}

void loop()
{
  String str = "";  
  for (int i=0; i<30; i++)
  {
    str = String(str +String(i,DEC));  // works fine
//    str = str +String(i,DEC);  // works fine
//    str = String(str) +String(i,DEC);  // crashes
//    str = String(str+ "-" +String(i,DEC)); // crashes
//    str = String(String(str) +String(i,DEC));  // crashes
//    str = str + "-" +String(i,DEC);  // crashes
    Serial.println(str);
  }
}
char outBuf[64];

void setup ()
{
  Serial.begin(9600);
}

void loop()
{
  for (int i=0; i<30; i++)
  {
      sprintf(outBuf,"This always works: %d",i);
      Serial.println(outBuf);
  }
}

Ok, nice workearound, but does not explain why the above crashes or freezes the arduino.

One is addition (byte, integer, long). The other is concatenation (string).

It would appear the "+=" does not work with concatenation, only addition.

If you look at WString.cpp in the Arduino core files, you will see that concatenation using += is implemented as concatenation.

It works by allocating a buffer large enough to contain the old + new string, then cating it. This appears to lead to memory fragmentation on ATmegas limited memory and stack environment.

Your workaround works or just treating all Strings as character arrays instead. This results in much lower over head. It does require you, as the programmer, to determine ahead of time what size the arrays should be. Which, in such a limited memory environment, is actually a good idea.

After changing my code not to use the String class anymore but use char arrays, i ran into another problem

void loop()
{
  char tx[100];
  long TestA = 1;
  word TestB = 1;
  
  sprintf (tx, "%d %d %d %d", TestA, 2, 3, 4);
  Serial.println(tx);

  sprintf (tx, "%d %d %d %d", TestB, 2, 3, 4);
  Serial.println(tx);
}

I would have expected the to outputs to be the same, but they are not. It outputs the following two lines:

1 0 2 3 1 2 3 4

Can anybody explain this to me? Isn't it possible to use a long or unsigned long with sprintf?

regards Mirko

%d is an int %ld is a long int

http://www.cplusplus.com/reference/clibrary/cstdio/printf/

OK, thanx for that info. I did not know that as i never needed %ld before ;-)

regards Mirko

In that case, you should know that

%u is unsigned int %lu is unsigned long