c'è [a] [...] perdita di memoria
Sicuramente sì.
Il riferimento alla memoria allocata dal 1 ° chiamata a aprintf()
viene sovrascritta dalla seconda chiamata a aprintf()
, quindi non c'è alcuna possibilità di free()
1 ° memoria allocata più, si "fughe di notizie".
Per risolvere questo problema introdurre un secondo (temporanea) puntatore:
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);
Un diverso e probabilmente più economico (più veloce come alcuni roba è gestire durante il tempo di compilazione, ma run-time) approccio a questo problema sarebbe il seguente:
#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);
L'aggiunta del controllo degli errori sulle chiamate di sistema viene lasciata al lettore come esercizio.
Un terzo approccio a questo solo utilizzando le funzioni standard 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);
Un diverso e probabilmente più economico (più veloce come alcuni roba è gestire durante il tempo di compilazione, ma run-time) approccio a questo problema sarebbe il seguente:
#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);
sì, stai perdendo memoria. la stringa con cui il primo asprintf ha creato e salvato un puntatore nel log ora viene cancellata/eliminata –
@MarcB: "* la stringa che il primo' asprintf 'ha creato [...] ora cancellato/passato * "Non è corretto, come "stringa", cioè la memoria che è stata allocata, ancora * è * allocata. Tuttavia il riferimento ad esso (come 1 ° memorizzato in 'log') è andato. Quindi la memoria non può essere più 'libera()' ed, che comunemente si chiama "perdita di memoria". – alk
@alkk: sì, brutto fraseggio da parte mia. il POINTER è morto/andato. –