avr-libc-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-libc-dev] [RFC] Joerg's new vsprint functions.


From: Joerg Wunsch
Subject: Re: [avr-libc-dev] [RFC] Joerg's new vsprint functions.
Date: Thu, 20 Nov 2003 09:57:14 +0100
User-agent: Mutt/1.2.5i

As Theodore A. Roth wrote:

> A common usage (according to google) is to do something like this:
> 
>   char *buf;
>   int length = snprintf (NULL, 0, fmt, ...);
>   buf = (char *)malloc (length+1);
>   sprintf (buf, fmt, ...);
>   ...
>   free (buf);
> 
> Basically, using snprintf to determine the desired buffer size prior to
> allocating the buffer by passing a NULL ptr. This seems like a
> legitimate thing to be able to do.

That ought to work.  I didn't test it, but effectively, fputc() is
used, and this function doesn't write anything to the buffer if the
buffer's size is 0:

        if (stream->flags & __SSTR) {
                if (stream->len < stream->size)
                        *stream->buf++ = c;

If 0 is passed for length, both stream->len and stream->size are 0, so
the test will fail, and nothing is written.  Consequently, stream->buf
may be NULL in that case (which is required by the standard, btw.).

An unchecked call to malloc() (as your snippet above indicates) is
always an error.  This might usually work in a VM environment (such as
Unix or Win32), but not checking the result is poor coding anyway, and
not covered by the standard.  Better code usually wraps the calls to
malloc() in their own function that performs exception handling (in
the simplest case, by calling abort()).  Sure, in a MCU environment,
it's not so obvious what to do when running out of memory...

> As for penalties, there's three ways to look at it.
> 
>   1. The caller has to check for NULL before every call to snprintf().

Nope.  Think of situations like this one:

   char mybuf[20];
   ...
   (void)snprintf(mybuf, sizeof mybuf, ...);

In this case, it's obvious that the buffer pointer will never be NULL,
no check is necessary.  The call to snprintf() (as opposed to
sprintf()) is just defensive programming so to avoid crashes resulting
from buffer overflows, while the implementor would usually expect
mybuf to be large enough to hold the result.  Many people hesitate to
use malloc() in an MCU environment, so I'd even expect the above to be
more frequently used there.
-- 
J"org Wunsch                                           Unix support engineer
address@hidden        http://www.interface-systems.de/~j/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]