Проблема в том, что вы пытаетесь изменить строковый литерал. Это приводит к тому, что поведение вашей программы не определено.
Сказать, что вам не разрешено изменять строковый литерал, является упрощением. Утверждение, что строковые литералы 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++, в основном Bjarne Stroustrup, не были так обеспокоены обратной совместимостью с C.)
Чувак - «это тест» - это STRING LITERAL. Это означает, что это * ЧИТАТЬ ТОЛЬКО * «массив символов». Вы даже можете уйти, пытаясь изменить его без сбоев на определенных платформах. Но это определенно нет-нет на * ЛЮБОЙ * платформе :) – paulsm4