This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Using asprintf without memory leaks


On Thu, Nov 26, 2015 at 5:21 PM, Ian Pilcher <arequipeno@gmail.com> wrote:
> asprintf(3) says:
>
>   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 is undefined.
>
> If -1 is returned, can I at least assume that any memory that was
> allocated has been freed?  If not, it's hard to see how asprintf can
> be used without risking memory leaks.

You have no guarantees that the implementation does not leak memory,
either for this interface, or any other interface.

You have only the contract as written in the glibc manual. Please be
aware that the specification as you quote from the man page is
non-normative.

A high quality implementation would attempt to free as much memory as
possible before returning the error. However, no guarantees are ever
given.

As a glibc developer I can speak to the quality of the implementation.
I can say that _IO_vasprintf/_IO_vsprintf (the functions that
impelement asprintf) should ensure the dynamically allocated buffer is
freed on error. I haven't audited all code paths, but every path I
know of and have worked on does the right thing and frees the buffer.

* If malloc fails, it returns -1.
* If the internal _IO_vsprintf fails, we free the allocated buffer and
return the error.
* If the final buffer shrinking fails we leave the larger buffer in place.

The only time the working buffer is not freed is when it's returned to
the caller for later freeing.

If you find a leak with valgrind please file a bug and we'll fix it.

Cheers,
Carlos.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]