На языке C показан фрагмент: char *s = "hello"; s[0] = 'H'; Объясните, почему это UB на многих платформах, как правильно изменить строку и какие альтернативы предлагает язык C в подобных ситуациях

20 Ноя в 08:27
3 +1
0
Ответы
1
Коротко и по делу.
Почему это UB:
- В коде
char *s = "hello";
s[0]=′H′;s[0] = 'H';s[0]=H; строка "hello" — строковый литерал, размещается в статической памяти и на многих платформах — в сегменте только для чтения (.rodata). По стандарту C попытка изменить содержимое строкового литерала — неопределённое поведение (UB). На некоторых реализациях это приведёт к аварийному завершению (segfault), на других — может «сработать» случайно, но это не гарантировано.
Как правильно изменить строку:
- Использовать автоматический массив (копию литерала):
char s[] = "hello";
s[0]=′H′;s[0] = 'H';s[0]=H; // легально
- Выделить память динамически и скопировать:
char *s = malloc(strlen("hello")+1strlen("hello")+1strlen("hello")+1);
strcpy(s, "hello");
s[0]=′H′;s[0] = 'H';s[0]=H;
free(s);
- В POSIX можно использовать strdup:
char *s = strdup("hello");
s[0]=′H′;s[0] = 'H';s[0]=H;
free(s);
Альтернативы и рекомендации в C:
- Если строка не должна изменяться, помечайте её как const:
const char *s = "hello"; // компилятор предупредит при попытке записи
- Для изменяемых строк — всегда держите модифицируемую копию (массив или malloc).
- Для удобства и безопасности используйте библиотечные функции (strdup/strcpy/strncpy) или собственные обёртки управления памятью.
Суть: строковый литерал нельзя надежно модифицировать — делайте копию (массив или динамическая память) или объявляйте указатель const.
20 Ноя в 08:34
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир