strlen() and sizeof()

Hi I see something strange here:
How can

char hi[] = "hi";
Serial.print("hi "); Serial.print(strlen(hi));
Serial.print(" "); Serial.println(sizeof(hi));// prints 2 3 - correct

char extra[10] = "extra";
Serial.print("extra "); Serial.print(strlen(extra));
Serial.print(" "); Serial.println(sizeof(extra));// prints 5 10 - correct

strcat(hi, extra);
Serial.print("hi "); Serial.print(strlen(hi));
Serial.print(" "); Serial.println(sizeof(hi));// 7 3 ???

how can sizeof still be 3 - surely 10? where is the extra now??

strcat(hi, extra);

The hi array was declared with a length of 3. It does not increase in size just because you concatenated another string to it. strlen(), however, uses the '\0' to find the end of the string so reports how many bytes the string takes

where is the extra now??

You wrote to memory that the program does not own so you may have overwritten another variable in the process

I would have said....

UKHeliBob:

strcat(hi, extra);

The hi array was declared with a length of 3. It does not increase in size just because you concatenated another string to it. strlen(), however, uses the '\0' to find the end of the string so...

...after it gets to the end of the space allocated to “hi” and hasn’t found a string terminator '\0', it keeps reading through memory it has no right accessing until it finds a zero byte and returns that length as the length of the string.

it keeps reading through memory it has no right accessing

The problem is not the reporting of the length of the concatenated string, which it does correctly, rather it is the writing to memory not allocated to the string in the first place

Here's an interesting side-effect of writing off the end of a buffer. This sketch produces an endless stream of :

hi 2 3
extra 5 10
hi 2 3
extra 5 10

It is crashing and restarting in one of these two lines:

  strcat(hi, extra);
  Serial.print(hi);   Serial.flush();

I had hoped to show that the "extra" array was getting overwritten by the strcat() but it didn't matter which order the declarations were in or whether they were local or global: the fourth line (when the sketch didn't crash) would show 'extra' undammaged.

char hi[] = "hi";
char extra[10] = "extra";


void setup()
{
  Serial.begin(115200);


  Serial.print(hi);
  Serial.print(" ");
  Serial.print(strlen(hi));
  Serial.print(" ");
  Serial.println(sizeof hi);  // prints 2  3  - correct
  Serial.flush();


  Serial.print(extra);
  Serial.print(" ");
  Serial.print(strlen(extra));
  Serial.print(" ");
  Serial.println(sizeof extra); // prints  5  10  - correct
  Serial.flush();


  strcat(hi, extra);
  Serial.print(hi);   Serial.flush();
  Serial.print(" ");  Serial.flush();
  Serial.print(strlen(hi));  Serial.flush();
  Serial.print(" ");  Serial.flush();
  Serial.println(sizeof hi);  Serial.flush();
  Serial.flush();


  Serial.print(extra);
  Serial.print(" ");
  Serial.print(strlen(extra));
  Serial.print(" ");
  Serial.println(sizeof extra); // prints  5  10  - correct
  Serial.flush();
}


void loop() {}