Найдите и объясните неопределённое поведение в этом фрагменте на C и предложите безопасные альтернативы (с сохранением функциональности):
char* bad() {
char buf[10]

3 Ноя в 19:22
4 +1
0
Ответы
1
Коротко — в этом фрагменте есть несколько проблем. Самая важная: возврат указателя на локальный массив приводит к неопределённому поведению (буфер живёт в стеке и перестаёт существовать при выходе из функции). Также в приведённом фрагменте синтаксическая ошибка (нет `;`) и отсутствует `return`.
Почему это UB
- Локальный массив: указатель, возвращённый из функции, будет указывать на область стека, которая может быть перезаписана — использование такого указателя после возврата даёт неопределённое поведение.
- Если буфер не инициализирован или при записи выход за границы (overflow), — тоже UB.
- Если буфер используется как C‑строка, отсутствие завершающего `'\0'` даёт UB при вызове строковых функций.
Безопасные альтернативы (функциональность сохранить — вернуть строку/буфер):
1) Выделение в куче (caller освобождает)
#include #include #include
char* good_malloc(void) {
char *buf = malloc(101010);
if (!buf) return NULL;
snprintf(buf, 101010, "%s", "hello"); // гарантированная NUL-терминация
return buf;
}
// вызов: char *s = good_malloc(); ... free(s);
2) Caller предоставляет буфер (без утечек, потокобезопасно)
#include #include
void good_out(char *out, size_t out_size) {
if (out_size == 0) return;
snprintf(out, out_size, "%s", "hello");
}
// вызов: char buf[101010]; good_out(buf, sizeof buf);
3) Статический буфер (простo, но не потокобезопасно/не реентерабельно)
#include
char* good_static(void) {
static char buf[101010];
strcpy(buf, "hello");
return buf;
}
// последующие вызовы перезапишут буфер
4) Использовать strdup (если строка известна или формируется во временном буфере)
#include
char* good_strdup(void) {
return strdup("hello"); // caller free()
}
Краткие рекомендации
- Предпочитайте вариант где caller освобождает память (malloc/strdup) или где caller предоставляет буфер.
- Никогда не возвращайте указатель на локальную переменную.
- Всегда гарантируйте NUL‑терминацию и избегайте переполнений (используйте snprintf/strlcpy/explicit bounds).
3 Ноя в 20:43
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир