Возможна ли в этой функции утечка памяти из-за отсутствия вызова free() при наличии вызова malloc()?
char * concat(const char * first, const char * second)
{
char * restrict result = NULL;
size_t first_length = strlen(first);
size_t second_length = strlen(second);
result = malloc(sizeof(char) * (first_length + second_length + 1));
if (result == NULL)
{
perror("Error: memory allocation failed.");
exit(EXIT_FAILURE);
}
memcpy(result, first, first_length);
memcpy(result + first_length, second, second_length + 1);
return result;
}
Функция предназначена для объединения двух строк за наименьшее время. Компилирую в режиме GCC --std=c2x.
Ответы (2 шт):
1.
Наличие сбалансированной пары malloc/free не гарантирует вас от утечек памяти:
#include <setjmp.h>
#include <stdlib.h>
jmp_buf buf;
void g() {
longjmp(buf, 1);
}
void f() {
char *p = malloc(42);
g();
free(p);
}
int main() {
if (!setjmp(buf)) {
f();
}
}
$ gcc -g leak.c $ valgrind ./a.out 2>&1 | grep lost ==273705== definitely lost: 42 bytes in 1 blocks ==273705== indirectly lost: 0 bytes in 0 blocks ==273705== possibly lost: 0 bytes in 0 blocks
2.
Отсутствие баланса в функции не означает что будет утечка:
#include <stdlib.h>
char *f() {
return malloc(42);
}
int main() {
char *buf = f();
/* тут используем буфер по назначению */
free(buf);
}
$ gcc -g ok.c $ valgrind ./a.out 2>&1 | grep lost
3.
Ваша функция способствует утечке памяти в случае когда malloc не может выделить достаточно памяти. С другой стороны вы сразу завершаете программу, а в таком случае утечку можно игнорировать.
Коротко и ясно: нет.
Более длинный ответ, ваша функция перекладывает ответственность освобождения памяти, на вызывающую сторону, от вас ничего не зависит. Если ваша функция выделила блок памяти, и отдала указатель наружу, вы теряете над ней контроль, все, функция как подпрограмма отработала, и завершилась, все что будет происходить далее, лежит на плечах вызывающей стороны.
P.s, я не понял смысла делать какие-то выводы от setjmp, longjmp, единственное что посоветовал бы, так это убрать выход из программы при ошибке выделения памяти. Это не забота данной функции. Верните пустой указатель, а вызывающая сторона пусть делает то что ей нужно.