Программа 1:

#include <iostream>
using namespace std;

int main() {
    string str;
    char temp = 'a';
    str += temp + "bc";
    cout << str;
    return 0;
}

Вывод:

Неизвестные символы

Программа 2 .

#include <iostream>
using namespace std;

int main() {
    string str;
    char temp = 'a';
    str += temp;
    str += "bc";
    cout << str;
    return 0;
}

Вывод:

abc

Почему оба выхода разные? Разве оба выхода не должны быть одинаковыми?

4
user12828132 3 Фев 2020 в 19:45

2 ответа

В классе std::string перегружены операторы + и +=, что позволяет использовать их для объединения std::string операторов друг с другом, с отдельными символами и массивами символов.

Но, как и в C, "bc" - это не std::string, а const char [3] (постоянный массив из 3 символов). Массивы часто автоматически конвертируются ( decay ) в указатели на их первые элементы. Это происходит и здесь.

str += "foobar"; добавляет символы, указанные указателем, один за другим, пока он не достигнет нулевого байта, заканчивающего строку.

Вы можете добавить целые числа к указателям: str += "foobar" + 3; добавит "bar" к строке.

В C ++ char являются просто маленькими целыми числами. Так что 'a' + "bc" на самом деле означает 97 + "bs" (при условии, что ваш компилятор использует ASCII, все обычные используют).

Это формирует указатель, который выходит за пределы массива и вызывает неопределенное поведение.

Случайные символы, которые вы видите, представляют собой содержимое памяти, расположенное в 97 байтах после массива "bc", которое заканчивается случайным нулевым байтом, который был в этой памяти.

0
HolyBlackCat 3 Фев 2020 в 17:04

Программа 1 в этой строке

str += temp + "bc";
  1. первые аргументы сложения оцениваются
  2. справа есть массив символов: const char[3]
  3. слева есть char, который можно автоматически преобразовать в int
  4. const char[3] ухудшается до const char *
  5. добавление int (97) и const char * возможно, но результаты выходят за пределы диапазона буфера.
  6. тогда вы используете basic_string::operator+=( const CharT* s );, но аргумент неверен. У вас переполнение буфера.

Программа 2 Не имеет такого неопределенного поведения, и используются операторы вида std::string.

Другая разумная версия:

str = str + temp + "bc";

Теперь каждое добавление будет создавать std::string в результате.

0
Marek R 3 Фев 2020 в 17:00