В чём отличие между 3мя способами инициализации строк?

не понимаю, в чём принципиальное отличие между 3-мя способами, результат везде раз идентичный

int main()
{
    char *line1 = new char;
    line1 = "abc";
    for (int i = 0; i < 3; i++)
    {
        cout << *(line1++);
    }
    cout << endl;

    char *line2 = "def";
    for (int i = 0; i < 3; i++)
    {
        cout << *(line2++);
    }
    cout << endl;

    char *line3 = new char[3]; //тут понятно, что отличие от 1го способа в том, что заранее задан размер
    line3 = "ghi";
    for (int i = 0; i < 3; i++)
    {
        cout << *(line3++);
    }
    return 0;
}

P.S. Примеры взяты из Лафоре


Ответы (1 шт):

Автор решения: NunOfIt
  1. char *line1 = new char; в данной строке вы выделяете память под одно значение char и записываете её адрес в указатель line1, затем в строке line1 = "abc"; вы его затираете, что приводит к утечке памяти, и записываете в line1 адрес на начало строки "abc";
  2. char *line2 = "def"; этот вариант продолжает и дополняет первую проблему, этот код у вас, конечно, скомпилируется, но т.к. "def" является константой, при любой попытке изменения значений line2 ваша программа умрёт смертью храбрых, если вы и собирались line2 использовать как константу, то измените данную строку на const char *line2 = "def";
  3. Та же проблема, что и в первом случае, вы выделяете память, а затем ссылку на неё затераете, ergo утечка памяти. Ну и не опять, а снова, проблема с "def" константой.

P.S. В соответсвтие с документацией (тык), до C++11 можно было присвоить string literal ("def") не константному char* неявным преобразованием (implicit conversion), эта возможность сохранялась для совместимости с C (т.е. char *line2 = "def"; легально):

String literals are convertible and assignable to non-const char* or wchar_t* in order to be compatible with C, where string literals are of types char[N] and wchar_t[N]. Such implicit conversion is deprecated.

Но, после C++11 такая запись будет приводить к ошибкам и требуется явное преобразование (т.е. char *line2 = const_cast<char*> ("def");)

String literals are not convertible or assignable to non-const CharT*. An explicit cast (e.g. const_cast) must be used if such conversion is wanted.

→ Ссылка