1

I created a program to concatenate two strings. However I get some extra characters included in the output string when the char array is too small.

Faulty code below:

char c[3] = "abc";
char d[3] = "def";
char result[8];

strcpy(result, c);
strcat(result, d);

printf("%s\n, result);

Prints abc{def�

Running the program without recompiling gives random chars each time. E.g abc�tdef� .

Changing the size of the result variable makes no difference:

char c[3] = "abc";
char d[3] = "def";
char result[6];

givesabcrdef�

I know that I need to change the size of the char arrays to 'c[4]' to produce expected output. This is to have space for null termination?

Furthermore, why are those symbols added? What decides why exactly those chars were included when they appear to be randomly selected?

Why does the result array acceept more chars than written? E.g 'char result[1]' gives 'abcdef' as output.

I've tried googling for answers.

hay
  • 11
  • 2
  • 2
    "*This is to have space for null termination?*" -- yes. – John Bollinger May 13 '23 at 13:26
  • "*What decides why **exactly** those chars were included when they appear to be randomly selected?*" At the C-language level, nothing. Your `strcpy()` and `strcat()` calls are overrunning the bounds of your arrays, and the resulting behavior is undefined. – John Bollinger May 13 '23 at 13:28
  • `char c[3] = "abc";` defines and initializes the array `c`, but `c` is not a string (since it does not have a terminator). `strcpy` requires that its 2nd argument be a string. Passing a non-string as the 2nd argument of strcpy is UB. – William Pursell May 13 '23 at 13:40
  • To fulfill `strcpy` requirements the array of chars can then be written as `char c[4]="abc\0"` or `char c[4]="abc"`? – hay May 13 '23 at 13:48
  • I'm still learning C, not trying to invoke undefined behaviour... – hay May 13 '23 at 14:04

2 Answers2

1

char[3] is not big enough to hold "abc", it needs to be char[4]. instead do

 char c[] = "abc";

and let the compiler work out the size for you, same for "def"

the resulting size will be 7 (not 6 or 8)

pm100
  • 48,078
  • 23
  • 82
  • 145
  • Yes I know that it needs to be at least 'char[4]' (even wrote so in the post). I'm more interested in the why's for this specific case. – hay May 13 '23 at 13:28
  • becuase `char[3]=abc` produces a c string that has no null at the end (theres no space for it) so strcat doesnt know where the end is, it keeps going to till it finds a \0. likewise strcat doesnt know where the end of "def" is because it has no \0 at the end either – pm100 May 13 '23 at 20:32
0
strcpy(result, c);

The above call to strcpy() invokes undefined behaviour¹ because the second argument is not a null-terminated string.

The subsequent calls to strcat() and printf() trigger undefined behaviour in a similar way.

I know that I need to change the size of the char arrays to 'c[4]' to produce expected output. This is to have space for null termination?

Indeed.

What decides why exactly those chars were included when they appear to be randomly selected?

At the C-language level, nothing. Your strcpy() and strcat() calls are overrunning the bounds of your arrays, and the resulting behavior is undefined. — John Bollinger

Why does the result array acceept more chars than written? E.g 'char result[1]' gives 'abcdef' as output.

Once a program reaches a state of undefined behaviour, no further assumption about the continuation of the execution of the program can be made.

To fulfill strcpy requirements the array of chars can then be written as char c[4]="abc\0" or char c[4]="abc"?

An explicit null-byte is not required. Simply:

char c[4] = "abc";

Or even better, let the compiler determine the length:

char c[] = "abc";

Footnote:

1 — From the C11 standard:

Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).

Harith
  • 4,663
  • 1
  • 5
  • 20