Найдите ошибку в следующем фрагменте на C и опишите возможные последствия (утечка памяти, двойное освобождение, неправильное поведение), предложите безопасную реализацию: char *s = malloc(10)
Ошибки в фрагменте - Отсутствует проверка результата `malloc`. При неудаче `malloc` возвращает `NULL` — последующее обращение к `s` приведёт к неопределённому поведению (сегфолт). - Если память выделялась для строк, не учтён нулевой терминатор: для строки длины nnn нужно выделять как минимум n+1n+1n+1 байт. - Нет инициализации буфера (если важно, используйте `calloc` или явно заполните). - Отсутствует `#include ` может дать предупреждение/ошибку в современных компиляторах или неверную декларацию в старых. - Не показано освобождение — возможна утечка памяти, а неверное повторное `free` — двойное освобождение. Возможные последствия - При `malloc` == `NULL` — программа аварийно завершится при использовании `s`. - Недостаточное выделение для строки — переполнение буфера, коррумпирование памяти, уязвимости безопасности. - Отсутствие `free` — утечка памяти; некорректное `free`/повторное `free` — неопределённое поведение. Безопасная реализация (пример) #include
#include
#include
int main(void) { size_t n = 10; /* желаемая длина строки */ char *s = calloc(n + 1, sizeof *s); /* выделяем n+1n+1n+1 байт и обнуляем */ if (s == NULL) { perror("calloc"); return EXIT_FAILURE; } /* пример безопасной записи: ограничиваем количество записываемых символов */ snprintf(s, n + 1, "%s", "hello"); /* гарантирует нуль-терминатор */ puts(s); free(s); return 0; } Ключевые моменты: всегда включайте нужные заголовки, проверяйте возврат `malloc`/`calloc`, выделяйте место для нулевого терминатора при работе со строками, и обязательно освобождайте память.
- Отсутствует проверка результата `malloc`. При неудаче `malloc` возвращает `NULL` — последующее обращение к `s` приведёт к неопределённому поведению (сегфолт).
- Если память выделялась для строк, не учтён нулевой терминатор: для строки длины nnn нужно выделять как минимум n+1n+1n+1 байт.
- Нет инициализации буфера (если важно, используйте `calloc` или явно заполните).
- Отсутствует `#include ` может дать предупреждение/ошибку в современных компиляторах или неверную декларацию в старых.
- Не показано освобождение — возможна утечка памяти, а неверное повторное `free` — двойное освобождение.
Возможные последствия
- При `malloc` == `NULL` — программа аварийно завершится при использовании `s`.
- Недостаточное выделение для строки — переполнение буфера, коррумпирование памяти, уязвимости безопасности.
- Отсутствие `free` — утечка памяти; некорректное `free`/повторное `free` — неопределённое поведение.
Безопасная реализация (пример)
#include #include #include
int main(void) {
size_t n = 10; /* желаемая длина строки */
char *s = calloc(n + 1, sizeof *s); /* выделяем n+1n+1n+1 байт и обнуляем */
if (s == NULL) {
perror("calloc");
return EXIT_FAILURE;
}
/* пример безопасной записи: ограничиваем количество записываемых символов */
snprintf(s, n + 1, "%s", "hello"); /* гарантирует нуль-терминатор */
puts(s);
free(s);
return 0;
}
Ключевые моменты: всегда включайте нужные заголовки, проверяйте возврат `malloc`/`calloc`, выделяйте место для нулевого терминатора при работе со строками, и обязательно освобождайте память.