Задать вопрос
@alikhan_hero

Почему строку можно изменить через массив, но через указатель нельзя?

Создавая строку как массив символов, мы можем легко менять ее отдельные символы
char hello[] = "alikhan";

hello[2] = 'f';

std::cout << hello << std::endl; // alfkhan


Также мы можем создать указатель на эту строку (массив символов) и менять саму строку через него
char hello[] = "alikhan";
char* phello = hello;

hello[2] = 'f';
phello[3]= 'f';

std::cout << hello << std::endl; // alffhan


Но создать изменяемую строку непосредственно через указатель на char мы не можем
char* hello = "hello"; // ошибка, перед char* должен быть const


Я новичок, подскажите пожалуйста, почему это происходит и чем обосновано.
  • Вопрос задан
  • 125 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 1
@Mercury13
Программист на «си с крестами» и не только
Потому что в Си++ — в отличие от Си — строковый литерал "hello" имеет тип const char[]. Как дополнительную подсказку, что даже если система (скажем, DOS) не имеет разделения памяти по типам и позволяет менять такие литералы — Windows имеет и не позволяет.

РАЗ. У указателя и массива несколько разная семантика
char hello1[] = "hello";   // массив длины 6, в изменяемом сегменте или стеке,
                         // данные скопированы из литерала, который
                         // сидит в неизменяемом сегменте
const char* hello2 = "hello";   // указатель направлен прямо на литерал,
                         // и попытка изменить его под Windows — вылет


ДВА. Компилятор имеет право спрессовать два литерала в один, и смена одного, скорее всего, сменит и другой. Не могу проверить на Windows — говорил же, что запись в строковый литерал под Windows приведёт к вылету — но, скорее всего, так будет. Что-то вроде
char* hello1 = const_cast<char*>("hello");
char* hello2 = const_cast<char*>("hello");
hello1[1] = 'U';   // hello2 = "hUllo" в системах вроде DOS, где не вылетит
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы