Размер массива назначения strcat

Возьмите следующую программу:

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
char a[8] = "Hello, ";
char b[7] = "world!";

strcat(a, b);

cout << a;

return 0;
}

Заметить, что a а также b имеют тот же размер, что и назначенные им строки.

документация утверждает, что для strcat(a, b) работать, a должен быть достаточно большим, чтобы содержать объединенную результирующую строку.

тем не менее, cout << a дисплеи "Hello, world!", Я вхожу в неопределенное поведение?

6

Решение

«Я вхожу в неопределенное поведение?»

Да. Область в конце [] была переписана. На этот раз это сработало, но могло принадлежать чему-то другому.

Здесь я использую структуру для управления макетом памяти и демонстрирую ее:

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
struct S {
char a[8];
char b[5];
char c[7];
};

S s;
strcpy( s.a , "Hello, " );
strcpy( s.b , "Foo!" );
strcpy( s.c , "world!" );strcat(s.a, s.c);

cout << s.a << endl;
cout << s.b << endl;

cin.get();

return 0;
}

Это выводит:

Hello, world!
orld!

Вместо:

Hello, world!
Foo!

Strcat () растоптал b [].

Обратите внимание, что в реальной жизни такие ошибки могут быть гораздо более тонкими и могут привести вас к удивлению, почему совершенно невинная функция вызывает 250 строк, которые позже вылетают и ужасно сгорают. 😉

РЕДАКТИРОВАТЬ: Могу ли я также рекомендовать использовать вместо strcat_s? Или, что еще лучше, std :: strings:

#include <string>
#include <iostream>

using namespace std;

int main()
{
string a = "Hello, ";
string b = "world!";
a = a + b;
cout << a;
}
11

Другие решения

Я вхожу в неопределенное поведение?

Да.


Если в документации сказано «a должен быть достаточно большим, чтобы содержать объединенную результирующую строку, почему ты просто не веришь в это? Что тут сомневаться?

3

В вашей программе массив a недостаточно велик, чтобы вместить результат. Следовательно, ваш код неверен и должен быть исправлен. По словам стандарта, вы действительно вводите неопределенное поведение, что означает, что оно может работать или не работать …

2

strcat делает то, что говорит на олове, а именно. копирует b в конец a, не заботясь о том, какие данные уже есть. Поскольку обе переменные находятся в стеке одна за другой, все работает. Но попробуй

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
char a[8] = "Hello, ";
int i =  10;
char b[7] = "world!";

strcat(a, b);

cout << a << i;

return 0;
}

И вы, вероятно, получите неожиданный результат, так как ваш стек был поврежден strcat

2

Это правильно …. Поведение не определено. Тот факт, что вы получили этот ответ, не означает, что в следующий раз он не потерпит крах, так как массив a очень маленький.

1
По вопросам рекламы [email protected]