С++. Конкатенация (объединение) строк

Для объединения строк str1 и str2 воспользуемся следующей конструкцией:

1) Создаем массив str3 для помещения конечного результата:
char str3[n]; n - необходимо задать исходя из потребностей;
2) Копируем в массив str1, например:
strcpy(str3, str1);
3) Объединяем заполненный массив со строкой str2:
strcat(str3, str2);

Данная конструкция связана с тем, что строка представляет собой строковую постоянную (литерал), а общая форма функций strcpy() и strcat() имеет следующий вид:
char* strcpy(char* dest, const char* source)
char* strcat(char* dest, const char* source)
dest - направление,
source - источник.

Здесь есть одна оговорка. Для объединения строк str1 и str2 прибегать к помощи массива str3[n] не совсем обязательно. Ведь можно их объединить и так. Допустим мы хотим к str1 присоединить str2, тогда - strcat(str1, str2). Это возможно только если str1 задан как:

char str1[m] = "Some text";

но не как:

char str1[] = "Some text";

При этом нужно указать значение m такое, чтобы размер массива str1 (ведь символьная строка есть ничто иное как массив, состоящий из символьных элементов и признака конца строки - NULL или '\0') мог содержать как свой набор символов, так и включить строку str2. По сути, это расширение области памяти символьной строки (точнее - массива). Небольшой пример.

#include <iostream>
#include <stdlib.h>

using namespace std;

int main()
{
  
    char str1[30] = "My favorite number is ";

    char str2[] = "16";

    strcat(str1, str2);

    cout << str1 << endl;

    return 0;



В данном случае все работоспособно и компилятор укажет нам зеленый свет. Но если попытаться сделать так:

#include <iostream>
#include <stdlib.h>

using namespace std;


int main()

{
  
    char str1[] = "My favorite number is ";
    char str2[] = "16";
    strcat(str1, str2);
    cout << str1 << endl;
    return 0;
}


то компилятор изначально не обругается, но на стадии дебага вылетит сообщение о стековом конфликте . Действительно, хотя здесь и нет синтаксической ошибки, все же ошибка всплывет тогда, когда функция попытается вписать str2 в ограниченную область памяти, то есть в массив str1, в домике которого есть место только для него.
Все логично, не так ли?