Проблема в том, что вы пытаетесь изменить строковый литерал.Это приводит к тому, что поведение вашей программы не определено.
Сказать, что вы не можете изменять строковый литерал, - это упрощение.Сказать, что строковые литералы const
неверно;это не так.
ПРЕДУПРЕЖДЕНИЕ: Далее следует отступление.
Строковый литерал "this is a test"
имеет выражение типа char[15]
(14 для длины плюс1 для окончания '\0'
).В большинстве контекстов, включая этот, такое выражение неявно преобразуется в указатель на первый элемент массива типа char*
.
Поведение при попытке изменить массив, на который ссылается строкалитерал не определен - не потому, что он const
(это не так), а потому, что в стандарте C конкретно сказано, что он не определен.
Некоторые компиляторы могут позволить вам сойти с рук.Ваш код может на самом деле модифицировать статический массив, соответствующий литералу (что может впоследствии вызвать большую путаницу).
Большинство современных компиляторов, тем не менее, хранят массив в постоянной памяти - не физическом ПЗУ, ав области памяти, которая защищена от модификации системой виртуальной памяти.Результатом попытки изменить такую память обычно является ошибка сегментации и сбой программы.
Так почему не являются строковыми литералами const
?Поскольку вам действительно не следует пытаться изменять их, это, безусловно, имеет смысл - и C ++ делает строковые литералы const
.Причина историческая.Ключевое слово const
не существовало до того, как оно было введено стандартом ANSI C 1989 года (хотя, возможно, до этого оно использовалось некоторыми компиляторами).Таким образом, предварительная ANSI-программа может выглядеть следующим образом:
#include <stdio.h>
print_string(s)
char *s;
{
printf("%s\n", s);
}
main()
{
print_string("Hello, world");
}
Не было способа обеспечить тот факт, что print_string
не разрешено изменять строку, на которую указывает s
.Создание строковых литералов const
в ANSI C нарушило бы существующий код, чего комитет ANSI C очень старался избежать.С тех пор не было хорошей возможности внести такие изменения в язык.(Разработчики C ++, в основном Бьярне Страуструп, не были так обеспокоены обратной совместимостью с C.)