Утечка памяти asprint нужна помощь, чтобы понять, откуда происходит утечка и возможные исправления
Примечание. Я вызвал эту функцию и освободил ее, но valgrind по-прежнему показывает ошибку. Этот код в основном принимает односвязный список с двумя данными coeff и exp. Это в основном преобразование полиномиального хранилища в связанный список, преобразованный в удобочитаемую строку. Я хочу, чтобы он был динамически распределен.
char *Poly_to_string(const Polynomial *p)
{
char *x = malloc(1);
int size;
while (p != NULL)
{
if((p->exp != 0) && (p->exp != 1))
{
size = asprintf(&x, "%s%dx^%d + ", x, p->coeff, p->exp);
if (size == -1)
{
exit(-1);
}
}
else if(p->exp == 1)
{
size = asprintf(&x, "%s%dx + ", x, p->coeff);
if (size == -1)
{
exit(-1);
}
}
else if(!p->exp)
{
size = asprintf(&x, "%s%d + ", x, p->coeff);
if (size == -1)
{
exit(-1);
}
}
p = p->next;
}
x[strlen(x) - 3] = '\0';
return x;
}
2 ответа
На справочной странице Linux (выделено жирным шрифтом):
ОПИСАНИЕ
Функции и
vasprintf()
являются аналогамиsprintf(3)
а такжеvsprintf(3)
, за исключением того, что они выделяют строку, достаточно большую для хранения вывода, включая завершающий нулевой байт ('\0'), и возвращают указатель на нее через первый аргумент. Этот указатель следует передать в free(3), чтобы освободить выделенное хранилище, когда оно больше не нужно.ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
В случае успеха эти функции возвращают количество напечатанных байтов, как и sprintf(3). Если выделение памяти было невозможным или произошла какая-то другая ошибка, эти функции вернут -1, а содержимое
strp
не определены.
Эта строка неверна:
char *x = malloc(1);
Это должно быть просто
char *x;
потому что, если
asprintf()
работает, он перезапишет содержимое
x
и вызвать память, выделенную в
char *x = malloc(1);
быть утечка.
РЕДАКТИРОВАТЬ
Цикл также необходимо решить, поскольку вы пытаетесь увеличить строку:
char *Poly_to_string(const Polynomial *p)
{
// start with an empty string that can be free()'d
// (if you don't have strdup() use malloc() and strcpy())
char *x = strdup("");
int size;
while (p != NULL)
{
// save the old malloc()'d value so it can be free()'d
char *oldValue = x;
if((p->exp != 0) && (p->exp != 1))
{
size = asprintf(&x, "%s%dx^%d + ", x, p->coeff, p->exp);
if (size == -1)
{
exit(-1);
}
}
else if(p->exp == 1)
{
size = asprintf(&x, "%s%dx + ", x, p->coeff);
if (size == -1)
{
exit(-1);
}
}
else if(!p->exp)
{
size = asprintf(&x, "%s%d + ", x, p->coeff);
if (size == -1)
{
exit(-1);
}
}
// free() the old value
free(oldValue);
p = p->next;
}
x[strlen(x) - 3] = '\0';
return x;
}
Есть и другие способы сделать это без начального
char *x = strdup("");
но тогда код становится намного сложнее.