Рассмотрите фрагмент на C: "char *s = \"hello\"; s[0] = 'H';" — объясните, что здесь происходит с памятью и почему такой код может привести к ошибке; как правильно изменить строку в этом случае?

19 Ноя в 10:17
2 +1
0
Ответы
1
Коротко: в строке
char *s = "hello";
переменная sss указывает на строковый литерал, который размещается в памяти с статическим временем жизни (обычно в сегменте только для чтения). Попытка изменить этот литерал:
s[0]=′H′;s[0] = 'H';s[0]=H; даёт неопределённое поведение — в лучшем случае ничего не произойдёт, в худшем программа упадёт с сегфолтом.
Почему так происходит (память):
- Сам указатель sss хранится в стеке (или там, где объявлен), но данные литерала — в отдельной области памяти с static storage duration. Многие реалии реализуют эту область как read-only, поэтому запись в неё запрещена. Стандарт C говорит, что модифицировать строковый литерал — UB.
Правильные способы изменить строку:
1) Использовать массив символов (копия литерала в изменяемой памяти):
char s[] = "hello";
тогда sss — массив размером 666 (включая нуль-терминатор), и
s[0]=′H′;s[0] = 'H';s[0]=H; корректно.
2) Выделить память динамически и скопировать:
char *s = malloc(strlen("hello") + 1);
if (s) {
strcpy(s, "hello");
s[0] = 'H';
free(s);
}
Вывод: нельзя менять строковый литерал через char∗char *char. Для изменения делайте копию в изменяемой памяти (массив или malloc).
19 Ноя в 10:23
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир