1
#include <stdio.h>
#include <string.h>
int main()
{
    char str1[30] = "First";
    char str2[6] = "Second";
    strcat(str1,str2);
    printf("%s",str1);
    return 0;
}

Output is "FirstSecondFirst" when I change str2 size 6 to 7, it functions properly.

I know that it continues to read without stopping if there is no null char, but I don't understand why the word 'First' is repeated.

Chris
  • 26,361
  • 5
  • 21
  • 42
bc a
  • 41
  • 2
  • 4
    Lucky stack layout. – Retired Ninja Jun 25 '23 at 06:27
  • 1
    Would you understand if the result was `"FirstSecond$#@$@#!"`? Or `"FirstSecond----"`? Or `"FirstSecondThird"`? Or `"FirstSecond – pmg Jun 25 '23 at 06:29
  • 2
    This is all undefined behaviour. `str2[]` is too small to contain the string it is intialized to, let alone the concatenation. – user207421 Jun 25 '23 at 06:43
  • 2
    `str2` is not a string because it has no null terminator. You may not pass it to any of the standard functions that expect a null-terminated string as the argument. That covers most functions in the standard C library — specifically `strcat()` but also functions such as `strlen()` and so on. – Jonathan Leffler Jun 25 '23 at 06:46
  • @bc a, "I know that it continues to read without stopping if there is no null char" --> Attempting read via to `str2` from outside `str2[]` is not "continues to read". It is _undefined behavior_ (UB). Anything may happen. – chux - Reinstate Monica Jun 25 '23 at 12:14

1 Answers1

6

Your str2 variable is not a string, since it does not allocate space for a null terminator. As such, passing it to strcat results in undefined behavior.

Given what you've seen, the likely situation you've encountered is that str2 is located immediately before str1 in memory. Because str2 is not null terminated, attempting to concatenate it to str1 loops back into str1 and concatenates "first" back onto str1. It stops because it does then encounter a null-terminator.

This particular behavior is just one possibility with undefined behavior and should not be counted on to repeat in any predictable manner.

You might also test this by simply printing str2 as a string without the concatenation, though as undefined behavior, it is not guaranteed to do the same again, so this may not be a useful test.

By allowing space for 7 characters in your fix, str2 is initialized with a null-terminator and is a valid string. As such, no undefined behavior is incurred.

If you wish to allocate a string exactly as much space as needed, you can simply not specify the dimensions of the char array.

char str2[] = "second";

This correctly allocates 7 characters.

Chris
  • 26,361
  • 5
  • 21
  • 42