Найдите и исправьте ошибки в фрагменте на C с управлением памятью:
char *dup_and_append(const char *s) { char *t = malloc(strlen(s)); strcat(t, "x"); return t; }
Объясните, какие типы ошибок возможны здесь и как их безопасно устранить

1 Ноя в 10:19
4 +1
0
Ответы
1
Ошибки в исходном коде и как их исправить — кратко:
1) Неправильный размер выделяемой памяти.
malloc получает strlen(s)strlen(s)strlen(s), но требуется место ещё для завершающего нуля и для добавляемого символа `'x'`. Нужно выделить strlen(s)+2strlen(s) + 2strlen(s)+2 байта.
2) Использование неинициализированной памяти с strcat — неопределённое поведение.
strcat ожидает, что в первой строке уже есть корректная C-строка (оканчивается `'\0'`). Надо сначала скопировать исходную строку в буфер (strcpy/memcpy/snprintf) или формировать результат вручную.
3) Отсутствует проверка результата malloc (NULL) — возможен crash при ошибке выделения.
4) Возможна целочисленная переполнение при вычислении размера для очень больших строк — надо проверять длину перед суммой.
5) Отсутствие include и документирования того, кто освобождает память (caller должен free()).
Исправленный безопасный вариант (простой и эффективный):
#include #include #include
char *dup_and_append(const char *s) {
if (s == NULL) return NULL;
size_t len = strlen(s);
/* проверка переполнения: нужен размер len + 2 */
if (len >= SIZE_MAX - 2) return NULL;
size_t size = len + 2; /* size=len+2 \text{size} = \text{len} + 2 size=len+2 */
char *t = malloc(size);
if (t == NULL) return NULL;
/* безопасно копируем и добавляем символ */
memcpy(t, s, len);
t[len] = 'x';
t[len + 1] = '\0';
return t;
}
Пояснения по безопасным альтернативам:
- Можно заменить memcpy + явная установка на strcpy + strcat, но strcpy допустим только если выделено достаточно памяти.
- Можно использовать snprintf: snprintf(t, size, "%s%c", s, 'x').
- На POSIX можно сделать char *t = strdup(s); then realloc to add один байт и append 'x' (не забудьте проверку результатов).
Короткий список исправлений, которые обязательно сделать:
- выделять strlen(s)+2strlen(s) + 2strlen(s)+2 байта;
- инициализировать буфер до использования strcat либо сразу формировать строку (memcpy + '\0' + добавление символа);
- проверять возвращаемое значение malloc;
- защищаться от целочисленного переполнения при вычислении размера;
- документировать, что вызывающий код обязан free() вернуть указатель.
1 Ноя в 10:47
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир