Setjmp, longjmp, malloc - как бороться с утечкой памяти - C (СИ)
Формулировка задачи:
Здравствуйте!
Вот небольшой тестовый пример, в котором, как я понимаю, free(buf) никогда не выполнится. exit(...) борится только с незакрытыми дескрипторами. Следовательно, утечка памяти.
Как корректно обработать такую ситуацию?
На ум приходит только обертки для malloc/free, которые будут запоминать что они выделяли/освобождали.
#include <setjmp.h>
#include <stdlib.h>
jmp_buf jmp_buffer;
void f2()
{
longjmp(jmp_buffer, 1);
}
void f1()
{
char *buf = (char *)malloc(5);
f2();
free(buf);
}
int main(int argc, const char *argv[])
{
if (setjmp(jmp_buffer) != 0) {
exit(EXIT_FAILURE);
}
f1();
exit(EXIT_SUCCESS);
}Решение задачи: «Setjmp, longjmp, malloc - как бороться с утечкой памяти»
textual
Листинг программы
#include <stdio.h>
#include <setjmp.h>
#include <stdlib.h>
jmp_buf jmp_buffer;
/* -------------------------------- */
static char *buf = NULL;
static void init_buf (void)
{
buf = (char*) malloc (5);
printf ("init buf\n");
}
static void close_buf (void)
{
printf ("close buf\n");
if (buf == NULL)
return;
printf ("real close buf\n");
free (buf);
}
/* -------------------------------- */
void f2()
{
longjmp(jmp_buffer, 1);
}
void f1()
{
init_buf();
f2();
close_buf(); /* <------ раз */
}
int main(int argc, const char *argv[])
{
if (setjmp(jmp_buffer) != 0) {
close_buf(); /* <------ два */
exit(EXIT_FAILURE);
}
f1();
exit(EXIT_SUCCESS);
}
Объяснение кода листинга программы
- Включаются необходимые заголовочные файлы:
, , . - Объявляется переменная типа jmp_buf — jmp_buffer.
- Определены две функции: init_buf() и close_buf(). Функция init_buf() выделяет память под буфер с помощью malloc(), выводит сообщение
init bufи возвращает void. Функция close_buf() освобождает память, выделенную под буфер, с помощью free(), выводит сообщениеreal close bufи возвращает void. - Определены две функции: f1() и f2(). Функция f1() вызывает функцию init_buf(), затем функцию f2() и в конце функцию close_buf(). Функция f2() вызывает longjmp(), передавая в качестве аргумента jmp_buffer. Функция f1() вызывает setjmp(), проверяет результат и если он не равен нулю, то вызывает функцию close_buf() и завершает работу программы с помощью exit().
- В функции main() происходит установка точки входа в программу с помощью setjmp(). Если результат не равен нулю, то вызывается функция close_buf() и программа завершается с помощью exit(). В противном случае происходит вызов функции f1(), которая в свою очередь вызывает функцию f2(). Точка входа в программу устанавливается с помощью setjmp().
- Программа завершается с помощью exit().