What happens to memory: char name[n]; vs char name[n] = "";

I apologize for asking this, but I've googled for about an hour invain, wasn't able to find what happens to memory when you just declare:

char name[3];

and when you declare and assign, like this:

char name[3] = "";

I see they're different, cause this doesn't work(does not print the correct output):

Serial.begin(115200);
while (!Serial) {}
char good[] = "Good ";
char currentYear[] = "2017";
char exclams[] = "!!!";
char msg[strlen(good) + strlen(currentYear) + strlen(exclams) + 1]; // just declaring
strcat(msg, good);
strcat(msg, currentYear);
strcat(msg, exclams);
Serial.println(msg);

and this does:

Serial.begin(115200);
while (!Serial) {}
char good[] = "Good ";
char currentYear[] = "2017";
char exclams[] = "!!!";
char msg[strlen(good) + strlen(currentYear) + strlen(exclams) + 1] = ""; // declaring and assigning
strcat(msg, good);
strcat(msg, currentYear);
strcat(msg, exclams);
Serial.println(msg);

What confuses me is that, in both cases,

sizeof(msg)

returns 13, that's the correct size the destination char buffer should have in this case.

strcat depends on both arrays being correctly terminated. Your first case doesn't do this; you just get any old junk in your array msg..

sizeof is simply the declared length of the msg array, which is correct in both cases because strlen is working on correctly terminated arrays.

So it depends on the fact that assignment adds the null terminating character (required for strcat to work fine) while declaration just reserve the space but doesn't write anything on it I guess. Faster than light, thank you : )

Serial.begin(115200);
while (!Serial) {}
char good[] = "Good ";
char currentYear[] = "2017";
char exclams[] = "!!!";
char msg[strlen(good) + strlen(currentYear) + strlen(exclams) + 1]; // just declaring
msg [0] = '\0';
strcat(msg, good);
strcat(msg, currentYear);
strcat(msg, exclams);
Serial.println(msg);

I use strcpy() for putting the first string in the buffer and then strcat() after that.

pert: I use strcpy() for putting the first string in the buffer and then strcat() after that.

So you would do this

char msg[strlen(str1) + ... + strlen(strn) + 1]= "";
strcpy(msg, str1);
strcat(msg, str2);
...
strcat(msg, strn);

Instead of this?

char msg[strlen(str1) + ... + strlen(strn) + 1]= "";
strcat(msg, str1);
strcat(msg, str2);
...
strcat(msg, strn);

Any particolar reason?

Yes, that makes the initialization of msg[] unnecessary because it copies str1 including it's null terminator to msg, once that string is in place the other strcat()s work correctly. Maybe it's a little more efficient since strcpy doesn't have to search msg for the null terminator to know where to start.

I compiled two minimal versions of your code for Uno with Arduino IDE 1.8.3:

void setup() {
  Serial.begin(115200);
  while (!Serial) {}
  char good[] = "Good ";
  char currentYear[] = "2017";
  char exclams[] = "!!!";
  char msg[strlen(good) + strlen(currentYear) + strlen(exclams) + 1] = "";
  strcat(msg, good);
  strcat(msg, currentYear);
  strcat(msg, exclams);
  Serial.println(msg);
}

void loop() {}

Sketch uses 1750 bytes (5%) of program storage space. Maximum is 32256 bytes. Global variables use 200 bytes (9%) of dynamic memory, leaving 1848 bytes for local variables. Maximum is 2048 bytes.

void setup() {
  Serial.begin(115200);
  while (!Serial) {}
  char good[] = "Good ";
  char currentYear[] = "2017";
  char exclams[] = "!!!";
  char msg[strlen(good) + strlen(currentYear) + strlen(exclams) + 1];
  strcpy(msg, good);
  strcat(msg, currentYear);
  strcat(msg, exclams);
  Serial.println(msg);
}

void loop() {}

Sketch uses 1734 bytes (5%) of program storage space. Maximum is 32256 bytes. Global variables use 198 bytes (9%) of dynamic memory, leaving 1850 bytes for local variables. Maximum is 2048 bytes.

I'm actually surprised that bringing in the additional function doesn't cause higher overhead

pert: I'm actually surprised that bringing in the additional function doesn't cause higher overhead

It's possible that strcat is implemented as a call to strlen and then a call to strcpy, so it may already be included.

I see... clever indeed! Thank you pert : )

Well, since we're here...

Uno with Arduino IDE 1.8.3:

void setup() {
  Serial.begin(115200);
  while (!Serial) {}
  char * good = PSTR("Good ");
  char * currentYear = PSTR("2017");
  char * exclams = PSTR("!!!");
  char msg[strlen_P(good) + strlen_P(currentYear) + strlen_P(exclams) + 1];
  strcpy_P(msg, good);
  strcat_P(msg, currentYear);
  strcat_P(msg, exclams);
  Serial.println(msg);
}

void loop() {}

Sketch uses 1584 byte (4%) of program storage space. Maximum is 32256 bytes. Global variables use 188 byte (9%) of dynamic memory, leaving 1860 bytes for local variables. Maximum is 2048 bytes.

:smiling_imp: