qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH] fix qemu_malloc() error check for size==0


From: Eduardo Habkost
Subject: Re: [Qemu-devel] [PATCH] fix qemu_malloc() error check for size==0
Date: Wed, 20 May 2009 00:28:33 -0300
User-agent: Mutt/1.5.18 (2008-05-17)

On Tue, May 19, 2009 at 11:49:54PM +0100, Jamie Lokier wrote:
> Eduardo Habkost wrote:
> > Excerpts from Jamie Lokier's message of Tue May 19 17:32:23 -0300 2009:
> > > Eduardo Habkost wrote:
> > > > Now, _that_ sounds like a really bad idea. realloc(NULL, n) is specified
> > > > to be equivalent to malloc(n).
> > > 
> > > No it isn't.  You can't make that substitution.
> > > 
> > > In the case where n == 0, realloc(NULL, n) is guaranteed to not
> > > allocate anything and return NULL, whereas malloc(n) does not
> > > guarantee that and in fact doesn't do that on a lot of implementations.
> > 
> > http://opengroup.org/onlinepubs/007908775/xsh/realloc.html
> > 
> > "If ptr is a null pointer, realloc() behaves like malloc() for the
> > specified size."
> > 
> > "If size is 0, either a null pointer or a unique pointer that can be
> > successfully passed to free() is returned."
> 
> Oh.  Thanks!  I stand corrected; sorry for propagating misinformation.

:-)

> 
> The relevant part in the standard which makes the above not contradict
> realloc's freeing behaviour, is "if size is 0 and __ptr is not a null
> pointer__, the object pointed to is freed."
> 
> All this creates a different problem, unfortunately:
> 
> If you do:
> 
>     p = malloc(n)         /* Arbitrary n, could be zero. */
>     free(p)
> 
> it works, but
> 
>     p = realloc(oldp, n)  /* Arbitrary n, could be zero. */
>     realloc(p, 0)
> 
> is not guaranteed to free the allocated block, if n == 0 && p == NULL.

It is a problem only if you drop the return value of the second
realloc() call. You shouldn't do that.

> 
> realloc(p, 0) is not equivalent to free(p) in this problem cases.

Yes. realloc(p, 0) frees p, but it is not exactly equivalent to free(p)
because it does more than freeing p: it returns a new value you need to
free later. You still need to save the returned value and eventually
pass it to free() (or maybe another realloc() call, whose return value
will need to be saved, and so on).

> 
> Which is IMHO another reason to either forbid n == 0, or warn about
> it, or change it unambiguously to n == 1 in the qemu_ wrappers.

The example you have shown ignores the return value of realloc() and
that's the cause of the problem, not the possiblity of n==0.

That's the beauty of it: n==0 and realloc(NULL, n) don't need to be
treated like a special case by the caller, it Just Works. The only thing
you need to be careful about is not checking for NULL if you call
realloc(p, 0) or malloc(0). And, obviously, it has the same requirements
that apply for any other allocations, such as freeing it eventually, and
not making any out-of-bounds dereference of the returned pointer.

> 
> While we're here, the C language FAQ adds:
> 
> Q: Is it legal to pass a null pointer as the first argument to
>     realloc? Why would you want to?
> 
> A: ANSI C sanctions this usage (and the related realloc(..., 0), which
>    frees), although several earlier implementations do not support it, so
>    it may not be fully portable.

Old implementations, I guess. Is there any implementation we care about
that does that?

-- 
Eduardo




reply via email to

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