Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
233 views
in Technique[技术] by (71.8m points)

c - asprint memory leak need help understand where leak is coming from and possible fixes

Note: I did call this function and free it main but valgrind still shows error. This code basically takes in a singly linked-list with two data coeff and exp. This is basically converting a polynomial store in a linked list converted to readable string. I looking to have it dynamic allocated.

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] = '';
    return x;
}
question from:https://stackoverflow.com/questions/65643146/asprint-memory-leak-need-help-understand-where-leak-is-coming-from-and-possible

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

From the Linux asprintf() man page (bolding mine):

DESCRIPTION

The functions asprintf() and vasprintf() are analogs of sprintf(3) and vsprintf(3), except that they allocate a string large enough to hold the output including the terminating null byte (''), and return a pointer to it via the first argument. This pointer should be passed to free(3) to release the allocated storage when it is no longer needed.

RETURN VALUE

When successful, these functions return the number of bytes printed, just like sprintf(3). If memory allocation wasn't possible, or some other error occurs, these functions will return -1, and the contents of strp are undefined.

This line is wrong:

char *x = malloc(1);

It should just be

char *x;

because if asprintf() works, it will overwrite the contents of x and cause the memory allocated in char *x = malloc(1); to be leaked.

EDIT

The looping also needs to be addressed, as you're trying to grow the string:

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] = '';
    return x;
}

There are other ways to do this without the initial char *x = strdup(""); but the code then becomes a lot more complex.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...