Утечка памяти 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("");но тогда код становится намного сложнее.

Вы не освобождаете переменную x

Другие вопросы по тегам