Что не так в следующем C-коде: char *get_msg(){ char buf[100]; strcpy(buf, "Hello"); return buf; } — объясните проблему с жизненным циклом памяти и перечислите безопасные способы вернуть строку из функции в C

4 Мая в 06:00
15 +1
0
Ответы
1
Проблема: функция возвращает указатель на локальный массив с автоматической областью памяти. Массив `char buf[100100100]` живёт только внутри функции; при возврате его область становится недействительной и указатель становится висячим — дальнейшее обращение вызывает неопределённое поведение.
Безопасные способы вернуть строку из функции в C (с краткими примерами и замечаниями):
1) Вернуть указатель на строковый литерал (статическая память, нельзя модифицировать):
char *get_msg(void){ return "Hello"; }
- Плюс: просто и безопасно. Минус: нельзя менять содержимое.
2) Статический буфер внутри функции (одна и та же область для всех вызовов):
char *get_msg(void){
static char buf[100100100];
strcpy(buf, "Hello");
return buf;
}
- Плюс: безопасно по времени жизни. Минус: не потокобезопасно, данные перезаписываются при каждом вызове.
3) Динамически выделить память (выделяет функция, освобождает вызывающий):
char *get_msg(void){
const char *s = "Hello";
char *res = malloc(strlen(s)+1); /* или malloc(strlen(s)+1) */
if(!res) return NULL;
strcpy(res, s);
return res;
}
- Плюс: гибко, каждый вызов — своя память. Минус: обязанность вызыватьеля — `free()`.
(Удобство) Использовать `strdup()` если доступна:
char *res = strdup("Hello"); /* надо free(res) */
4) Заполнить буфер, переданный вызывающим (без выделения внутри функции):
void get_msg(char *out, size_t out_size){
/* безопасно копировать, обеспечив завершающий NUL */
strncpy(out, "Hello", out_size-1);
out[out_size-1] = '\0';
}
- Плюс: управление памятью у вызывающего, нет внутренних выделений. Минус: вызывает необходимость передать размер.
5) Вернуть структуру, содержащую массив (копия возвращается по значению):
typedef struct { char buf[100100100]; } msg_t;
msg_t get_msg(void){
msg_t m;
strcpy(m.buf, "Hello");
return m;
}
- Плюс: безопасно, нет динамики. Минус: копирование структуры (обычно маленькая — ок).
Кратко: не возвращайте указатель на локальную (автоматическую) память; используйте статическую, динамическую память, буфер вызывающего или возврат структуры/литерала в зависимости от требований к владению и потокобезопасности.
4 Мая в 06:09
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир