находится там [а] [...] утечку памяти
Определенно да.
Ссылка на память, выделенную на 1-ом вызове aprintf()
получает перезаписаны 2 вызова aprintf()
, так что нет никаких шансов на free()
1-й выделенной памяти больше, это «утечка».
Чтобы исправить это ввести 2-й (временный) указатель:
char name[] = "C";
char * log = NULL;
{
char * log_tmp = NULL;
asprintf(&log_tmp, "Hello: %s", name);
if (known_person == true)
{
asprintf(&log, "%s, %s", log_tmp, ", my old friend.");
free(log_tmp);
}
else
{
log = log_tmp;
}
}
/* Use log. */
free(log);
Другой и, вероятно, дешевле (быстрее, так как некоторые вещи обрабатывать во время компиляции, но время выполнения) подход к этой проблеме было бы следующие:
#define FORMAT_STR "Hello: %s"
#define FORMAT_SUFFIX_STR ", my old friend."
...
char name[] = "C";
char * log = NULL;
{
char format[sizeof FORMAT_STR""FORMAT_SUFFIX_STR + 1] = FORMAT_STR;
if (known_person == true)
{
strcat(format, FORMAT_SUFFIX_STR);
}
asprintf(&log, format, name);
}
/* Use log. */
free(log);
Добавление проверки ошибок в системные вызовы оставляется читателю в качестве упражнения.
3-й подход к этому только с использованием функций стандарта C является:
char name[] = "C";
char * log = NULL;
{
char * log_tmp = NULL;
asprintf(&log_tmp, "Hello: %s", name);
if (known_person == true)
{
asprintf(&log, "%s, %s", log_tmp, ", my old friend.");
free(log_tmp);
}
else
{
log = log_tmp;
}
}
/* Use log. */
free(log);
Другой и, вероятно, дешевле (быстрее, так как некоторые вещи обрабатывать во время компиляции, но время выполнения) подход к этой проблеме будет следующее:
#define FORMAT_STR "Hello: %s"
#define FORMAT_SUFFIX_STR ", my old friend."
...
char name[] = "C";
char * log = NULL;
{
char format[sizeof FORMAT_STR""FORMAT_SUFFIX_STR + 1] = FORMAT_STR;
if (known_person == true)
{
strcat(format, FORMAT_SUFFIX_STR);
}
{
int s = snprintf(NULL, 0, format, name);
if (-1 == s)
{
/* failure */
}
else
{
log = malloc(s + 1);
if (NULL == log)
{
/* failure */
}
else
{
if (-1 == sprintf(log, format, name))
{
/* failure */
}
}
}
}
}
free(log);
Да, вы просачиваете память. строка, в которой первый asprintf создал и сохранил указатель на журнал, теперь удален/ушел –
@MarcB: «* строка, в которой первый« asprintf »создан [...] теперь удален/удален *« Это неверно, как «строка», то есть выделенная память, все еще * выделена. Однако ссылка на него (как первая сохранена в 'log') исчезла. Таким образом, память больше не может быть 'free()' ed, которая обычно называется «утечкой памяти». – alk
@alkk: Да, плохая фразировка с моей стороны. УКАЗАТЕЛЬ мертв/ушел. –