public inbox for linux-man@vger.kernel.org
 help / color / mirror / Atom feed
* Error in man page: realloc(ptr, 0) is not equivalent to free(ptr)
@ 2008-02-21  6:26 Lasse Kärkkäinen
       [not found] ` <47BD19AF.4000101-ze05kZMmeybHOG6cAo2yLw@public.gmane.org>
  0 siblings, 1 reply; 10+ messages in thread
From: Lasse Kärkkäinen @ 2008-02-21  6:26 UTC (permalink / raw)
  To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w; +Cc: linux-man-u79uwXL29TY76Z2rM5mHXA

The man page says that realloc(ptr, 0) is equivalent to free, even
though it isn't. The text on the man page says

---
realloc()  changes the size of the memory block pointed to by ptr to
size bytes.  The contents will be unchanged to the minimum of the old
and new sizes;  newly  allocated memory  will  be  uninitialized.   If
ptr  is  NULL,  the call is equivalent to malloc(size); if size is equal
to zero, the call is equivalent to free(ptr).  Unless ptr is NULL, it
must have been returned by an earlier call to malloc(), calloc() or
realloc().  If the area pointed to was moved, a free(ptr) is done.
[...]
realloc()  returns a pointer to the newly allocated memory, which is
suitably aligned for any kind of variable and may be different from ptr,
or NULL if the request fails.  If  size  was equal to 0, either NULL or
a pointer suitable to be passed to free() is returned.  If realloc()
fails the original block is left untouched; it is not freed or moved.
---

The C99 standard says:

---
7.20.3.4 The realloc function
Synopsis
        #include <stdlib.h>
        void *realloc(void *ptr, size_t size);
Description

The realloc function deallocates the old object pointed to by ptr and
returns a pointer to a new object that has the size specified by size.
The contents of the new object shall be the same as that of the old
object prior to deallocation, up to the lesser of the new and old sizes.
Any bytes in the new object beyond the size of the old object have
indeterminate values.

If ptr is a null pointer, the realloc function behaves like the malloc
function for the specified size. Otherwise, if ptr does not match a
pointer earlier returned by the calloc, malloc, or realloc function, or
if the space has been deallocated by a call to the free or realloc
function, the behavior is undefined. If memory for the new object cannot
be allocated, the old object is not deallocated and its value is unchanged.

Returns

The realloc function returns a pointer to the new object (which may have
the same value as a pointer to the old object), or a null pointer if the
new object could not be allocated.
---


glibc implements the behavior specified by the standard, not that
specified on the man page. realloc(NULL, 0) is equivalent to malloc(24),
actually allocating the minimum block (which is 24 bytes at least on my
architecture) instead of doing nothing like free(NULL) does.

One test case to demonstrate this:

#include <stdlib.h>

int main(void) {
    void* ptr = malloc(100);
    // Man page says this is equivalent to free(ptr)
    ptr = realloc(ptr, 0);
    // ... but according to Valgrind, this program leaks memory,
    // unless you add
    free(ptr);
    // ... which should be invalid (double free)
}

Another one (as requested by jeffz on #gnu):

#include <stdlib.h>

int main(void) {
    for (size_t i = 0; i < 0x7FFFFFFF; ++i) {
        void* ptr = realloc(NULL, 0);
    }
}

According to the man page, this program should not allocate any memory,
but it ends up allocating several gigabytes until OOM killer takes care
of it.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Error in man page: realloc(ptr, 0) is not equivalent to free(ptr)
       [not found] ` <47BD19AF.4000101-ze05kZMmeybHOG6cAo2yLw@public.gmane.org>
@ 2008-02-21  6:59   ` Mike Frysinger
       [not found]     ` <200802210159.03465.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
  0 siblings, 1 reply; 10+ messages in thread
From: Mike Frysinger @ 2008-02-21  6:59 UTC (permalink / raw)
  To: Lasse Kärkkäinen
  Cc: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w,
	linux-man-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 1501 bytes --]

On Thursday 21 February 2008, Lasse Kärkkäinen wrote:
> The man page says that realloc(ptr, 0) is equivalent to free, even
> though it isn't. The text on the man page says
>
> ---
> realloc()  changes the size of the memory block pointed to by ptr to
> size bytes.  The contents will be unchanged to the minimum of the old
> and new sizes;  newly  allocated memory  will  be  uninitialized.   If
> ptr  is  NULL,  the call is equivalent to malloc(size); if size is equal
> to zero, the call is equivalent to free(ptr).  Unless ptr is NULL, it
> must have been returned by an earlier call to malloc(), calloc() or
> realloc().  If the area pointed to was moved, a free(ptr) is done.
> [...]
> realloc()  returns a pointer to the newly allocated memory, which is
> suitably aligned for any kind of variable and may be different from ptr,
> or NULL if the request fails.  If  size  was equal to 0, either NULL or
> a pointer suitable to be passed to free() is returned.  If realloc()
> fails the original block is left untouched; it is not freed or moved.

i would just word it to say that when realloc() is given a size of 0, it is 
implementation defined as to the behavior, but it tends to match the behavior 
of malloc(0) (which too is implementation defined).  POSIX and C99 allow both 
cases to return either a NULL pointer or a "unique" pointer.  glibc will 
return a unique pointer (which cannot actually be used to store anything), 
but uClibc may return NULL.
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 827 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Error in man page: realloc(ptr, 0) is not equivalent to free(ptr)
       [not found]     ` <200802210159.03465.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
@ 2008-02-22 10:15       ` Michael Kerrisk
       [not found]         ` <cfd18e0f0802220215l6e61ab90h4a2d9b2e3e2a194d-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 10+ messages in thread
From: Michael Kerrisk @ 2008-02-22 10:15 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: Lasse Kärkkäinen, linux-man-u79uwXL29TY76Z2rM5mHXA

On Thu, Feb 21, 2008 at 7:59 AM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org> wrote:
> On Thursday 21 February 2008, Lasse Kärkkäinen wrote:
>  > The man page says that realloc(ptr, 0) is equivalent to free, even
>  > though it isn't. The text on the man page says
>  >
>  > ---
>  > realloc()  changes the size of the memory block pointed to by ptr to
>  > size bytes.  The contents will be unchanged to the minimum of the old
>  > and new sizes;  newly  allocated memory  will  be  uninitialized.   If
>  > ptr  is  NULL,  the call is equivalent to malloc(size); if size is equal
>  > to zero, the call is equivalent to free(ptr).  Unless ptr is NULL, it
>  > must have been returned by an earlier call to malloc(), calloc() or
>  > realloc().  If the area pointed to was moved, a free(ptr) is done.
>  > [...]
>  > realloc()  returns a pointer to the newly allocated memory, which is
>  > suitably aligned for any kind of variable and may be different from ptr,
>  > or NULL if the request fails.  If  size  was equal to 0, either NULL or
>  > a pointer suitable to be passed to free() is returned.  If realloc()
>  > fails the original block is left untouched; it is not freed or moved.
>
>  i would just word it to say that when realloc() is given a size of 0, it is
>  implementation defined as to the behavior, but it tends to match the behavior
>  of malloc(0) (which too is implementation defined).  POSIX and C99 allow both
>  cases to return either a NULL pointer or a "unique" pointer.  glibc will
>  return a unique pointer (which cannot actually be used to store anything),
>  but uClibc may return NULL.
>  -mike

Lasse, thanks for raising this; Mike, thanks for your input.

For man-pages-2.79, I propose to amend the description of realloc() to be:

       realloc() changes the size of the memory block pointed to
       by  ptr to size bytes.  The contents will be unchanged to
       the minimum of the old and  new  sizes;  newly  allocated
       memory  will  be uninitialized.  If ptr is NULL, then the
       call is equivalent to malloc(size); if size is  equal  to
       zero, and ptr is not NULL, then the call is equivalent to
       free(ptr).   Unless  ptr  is  NULL,  it  must  have  been
       returned  by  an  earlier  call  to malloc(), calloc() or
       realloc().  If the area pointed to was moved, a free(ptr)
       is done.

Note that the page already says the following about malloc(0):

       If size is 0, then malloc() returns either NULL, or a unique
       pointer value that can later be successfully passed to free().

Does this seem okay to you folks?

Cheers,

Michael


-- 
Michael Kerrisk
Maintainer of the Linux man-pages project
http://www.kernel.org/doc/man-pages/
Want to report a man-pages bug?  Look here:
http://www.kernel.org/doc/man-pages/reporting_bugs.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Error in man page: realloc(ptr, 0) is not equivalent to free(ptr)
       [not found]         ` <cfd18e0f0802220215l6e61ab90h4a2d9b2e3e2a194d-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2008-02-23  6:38           ` Mike Frysinger
       [not found]             ` <200802230138.11461.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
  2008-02-23  8:10           ` Chris "ク" Heath
  1 sibling, 1 reply; 10+ messages in thread
From: Mike Frysinger @ 2008-02-23  6:38 UTC (permalink / raw)
  To: Michael Kerrisk
  Cc: Lasse Kärkkäinen, linux-man-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 3021 bytes --]

On Friday 22 February 2008, Michael Kerrisk wrote:
> On Thu, Feb 21, 2008 at 7:59 AM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org> wrote:
> > On Thursday 21 February 2008, Lasse Kärkkäinen wrote:
> >  > The man page says that realloc(ptr, 0) is equivalent to free, even
> >  > though it isn't. The text on the man page says
> >  >
> >  > ---
> >  > realloc()  changes the size of the memory block pointed to by ptr to
> >  > size bytes.  The contents will be unchanged to the minimum of the old
> >  > and new sizes;  newly  allocated memory  will  be  uninitialized.   If
> >  > ptr  is  NULL,  the call is equivalent to malloc(size); if size is
> >  > equal to zero, the call is equivalent to free(ptr).  Unless ptr is
> >  > NULL, it must have been returned by an earlier call to malloc(),
> >  > calloc() or realloc().  If the area pointed to was moved, a free(ptr)
> >  > is done. [...]
> >  > realloc()  returns a pointer to the newly allocated memory, which is
> >  > suitably aligned for any kind of variable and may be different from
> >  > ptr, or NULL if the request fails.  If  size  was equal to 0, either
> >  > NULL or a pointer suitable to be passed to free() is returned.  If
> >  > realloc() fails the original block is left untouched; it is not freed
> >  > or moved.
> >
> >  i would just word it to say that when realloc() is given a size of 0, it
> > is implementation defined as to the behavior, but it tends to match the
> > behavior of malloc(0) (which too is implementation defined).  POSIX and
> > C99 allow both cases to return either a NULL pointer or a "unique"
> > pointer.  glibc will return a unique pointer (which cannot actually be
> > used to store anything), but uClibc may return NULL.
> >  -mike
>
> Lasse, thanks for raising this; Mike, thanks for your input.
>
> For man-pages-2.79, I propose to amend the description of realloc() to be:
>
>        realloc() changes the size of the memory block pointed to
>        by  ptr to size bytes.  The contents will be unchanged to
>        the minimum of the old and  new  sizes;  newly  allocated
>        memory  will  be uninitialized.  If ptr is NULL, then the
>        call is equivalent to malloc(size); if size is  equal  to
>        zero, and ptr is not NULL, then the call is equivalent to
>        free(ptr).   Unless  ptr  is  NULL,  it  must  have  been
>        returned  by  an  earlier  call  to malloc(), calloc() or
>        realloc().  If the area pointed to was moved, a free(ptr)
>        is done.

a quick read and it leaves me wondering "what if i call realloc(NULL, 0) ?".  
if i re-read it a few times, i can work out that the documentation, by not 
saying anything about size in the first statement, implies that malloc(size) 
is for all values of size.  but perhaps that should be made explicit ?

... If ptr is NULL, then the call is equivalent to malloc(size) for all values 
of size; ...

otherwise, it looks good to me, thanks
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 827 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Error in man page: realloc(ptr, 0) is not equivalent to free(ptr)
       [not found]         ` <cfd18e0f0802220215l6e61ab90h4a2d9b2e3e2a194d-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  2008-02-23  6:38           ` Mike Frysinger
@ 2008-02-23  8:10           ` Chris "ク" Heath
       [not found]             ` <1203754246.3021.104.camel-DBi1IKlRe8YXiSwHZUBl+UgmxNRb6L7S@public.gmane.org>
  1 sibling, 1 reply; 10+ messages in thread
From: Chris "ク" Heath @ 2008-02-23  8:10 UTC (permalink / raw)
  To: Michael Kerrisk
  Cc: Mike Frysinger, Lasse Kärkkäinen,
	linux-man-u79uwXL29TY76Z2rM5mHXA

On Fri, 2008-02-22 at 11:15 +0100, Michael Kerrisk wrote:
> On Thu, Feb 21, 2008 at 7:59 AM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org> wrote:
> > On Thursday 21 February 2008, Lasse Kärkkäinen wrote:
> >  > The man page says that realloc(ptr, 0) is equivalent to free, even
> >  > though it isn't. The text on the man page says
> >  >
> >  > ---
> >  > realloc()  changes the size of the memory block pointed to by ptr to
> >  > size bytes.  The contents will be unchanged to the minimum of the old
> >  > and new sizes;  newly  allocated memory  will  be  uninitialized.   If
> >  > ptr  is  NULL,  the call is equivalent to malloc(size); if size is equal
> >  > to zero, the call is equivalent to free(ptr).  Unless ptr is NULL, it
> >  > must have been returned by an earlier call to malloc(), calloc() or
> >  > realloc().  If the area pointed to was moved, a free(ptr) is done.
> >  > [...]
> >  > realloc()  returns a pointer to the newly allocated memory, which is
> >  > suitably aligned for any kind of variable and may be different from ptr,
> >  > or NULL if the request fails.  If  size  was equal to 0, either NULL or
> >  > a pointer suitable to be passed to free() is returned.  If realloc()
> >  > fails the original block is left untouched; it is not freed or moved.
> >
> >  i would just word it to say that when realloc() is given a size of 0, it is
> >  implementation defined as to the behavior, but it tends to match the behavior
> >  of malloc(0) (which too is implementation defined).  POSIX and C99 allow both
> >  cases to return either a NULL pointer or a "unique" pointer.  glibc will
> >  return a unique pointer (which cannot actually be used to store anything),
> >  but uClibc may return NULL.
> >  -mike
> 
> Lasse, thanks for raising this; Mike, thanks for your input.
> 
> For man-pages-2.79, I propose to amend the description of realloc() to be:
> 
>        realloc() changes the size of the memory block pointed to
>        by  ptr to size bytes.  The contents will be unchanged to
>        the minimum of the old and  new  sizes;  newly  allocated
>        memory  will  be uninitialized.  If ptr is NULL, then the
>        call is equivalent to malloc(size); if size is  equal  to
>        zero, and ptr is not NULL, then the call is equivalent to
>        free(ptr).   Unless  ptr  is  NULL,  it  must  have  been
>        returned  by  an  earlier  call  to malloc(), calloc() or
>        realloc().  If the area pointed to was moved, a free(ptr)
>        is done.

Hmmm.  The phrase

                                           if size is  equal  to
       zero, and ptr is not NULL, then the call is equivalent to
       free(ptr).

seems to contradict the following sentence, found under RETURN VALUES:

                              If size was equal to 0, either NULL
        or a pointer suitable to be passed to free() is returned.  

If realloc(ptr, 0) can return a non-NULL pointer, then it isn't
equivalent to free(ptr).

So which one is correct?  My tests with glibc 2.6 indicate that
realloc(ptr, 0) always returns NULL, so it IS equivalent to free(ptr).
However, I don't know if that is guaranteed to always be the case.

Chris


> Note that the page already says the following about malloc(0):
> 
>        If size is 0, then malloc() returns either NULL, or a unique
>        pointer value that can later be successfully passed to free().
> 
> Does this seem okay to you folks?
> 
> Cheers,
> 
> Michael
> 
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Error in man page: realloc(ptr, 0) is not equivalent to free(ptr)
       [not found]             ` <1203754246.3021.104.camel-DBi1IKlRe8YXiSwHZUBl+UgmxNRb6L7S@public.gmane.org>
@ 2008-02-23  8:41               ` Mike Frysinger
  2008-02-26 15:12               ` Michael Kerrisk
  1 sibling, 0 replies; 10+ messages in thread
From: Mike Frysinger @ 2008-02-23  8:41 UTC (permalink / raw)
  To: Chris ク Heath
  Cc: Michael Kerrisk, Lasse Kärkkäinen,
	linux-man-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 3784 bytes --]

On Saturday 23 February 2008, Chris ク Heath wrote:
> On Fri, 2008-02-22 at 11:15 +0100, Michael Kerrisk wrote:
> > On Thu, Feb 21, 2008 at 7:59 AM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org> wrote:
> > > On Thursday 21 February 2008, Lasse Kärkkäinen wrote:
> > >  > The man page says that realloc(ptr, 0) is equivalent to free, even
> > >  > though it isn't. The text on the man page says
> > >  >
> > >  > ---
> > >  > realloc()  changes the size of the memory block pointed to by ptr to
> > >  > size bytes.  The contents will be unchanged to the minimum of the
> > >  > old and new sizes;  newly  allocated memory  will  be 
> > >  > uninitialized.   If ptr  is  NULL,  the call is equivalent to
> > >  > malloc(size); if size is equal to zero, the call is equivalent to
> > >  > free(ptr).  Unless ptr is NULL, it must have been returned by an
> > >  > earlier call to malloc(), calloc() or realloc().  If the area
> > >  > pointed to was moved, a free(ptr) is done. [...]
> > >  > realloc()  returns a pointer to the newly allocated memory, which is
> > >  > suitably aligned for any kind of variable and may be different from
> > >  > ptr, or NULL if the request fails.  If  size  was equal to 0, either
> > >  > NULL or a pointer suitable to be passed to free() is returned.  If
> > >  > realloc() fails the original block is left untouched; it is not
> > >  > freed or moved.
> > >
> > >  i would just word it to say that when realloc() is given a size of 0,
> > > it is implementation defined as to the behavior, but it tends to match
> > > the behavior of malloc(0) (which too is implementation defined).  POSIX
> > > and C99 allow both cases to return either a NULL pointer or a "unique"
> > > pointer.  glibc will return a unique pointer (which cannot actually be
> > > used to store anything), but uClibc may return NULL.
> > >  -mike
> >
> > Lasse, thanks for raising this; Mike, thanks for your input.
> >
> > For man-pages-2.79, I propose to amend the description of realloc() to
> > be:
> >
> >        realloc() changes the size of the memory block pointed to
> >        by  ptr to size bytes.  The contents will be unchanged to
> >        the minimum of the old and  new  sizes;  newly  allocated
> >        memory  will  be uninitialized.  If ptr is NULL, then the
> >        call is equivalent to malloc(size); if size is  equal  to
> >        zero, and ptr is not NULL, then the call is equivalent to
> >        free(ptr).   Unless  ptr  is  NULL,  it  must  have  been
> >        returned  by  an  earlier  call  to malloc(), calloc() or
> >        realloc().  If the area pointed to was moved, a free(ptr)
> >        is done.
>
> Hmmm.  The phrase
>
>                                            if size is  equal  to
>        zero, and ptr is not NULL, then the call is equivalent to
>        free(ptr).
>
> seems to contradict the following sentence, found under RETURN VALUES:
>
>                               If size was equal to 0, either NULL
>         or a pointer suitable to be passed to free() is returned.
>
> If realloc(ptr, 0) can return a non-NULL pointer, then it isn't
> equivalent to free(ptr).
>
> So which one is correct?  My tests with glibc 2.6 indicate that
> realloc(ptr, 0) always returns NULL, so it IS equivalent to free(ptr).
> However, I don't know if that is guaranteed to always be the case.

this isnt a question that can be answered here.  you would have to ask for 
clarification on the open group mailing list as they are the ones who 
maintain the POSIX documentation.

for the purposes of the man page, i think this can be ignored.  or replace the 
sentence "the call is equivalent to free(ptr)" with "the ptr is freed".
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 827 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Error in man page: realloc(ptr, 0) is not equivalent to free(ptr)
       [not found]             ` <200802230138.11461.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
@ 2008-02-26 15:12               ` Michael Kerrisk
  0 siblings, 0 replies; 10+ messages in thread
From: Michael Kerrisk @ 2008-02-26 15:12 UTC (permalink / raw)
  To: Mike Frysinger
  Cc: Michael Kerrisk, Lasse Kärkkäinen,
	linux-man-u79uwXL29TY76Z2rM5mHXA



Mike Frysinger wrote:
> On Friday 22 February 2008, Michael Kerrisk wrote:
>> On Thu, Feb 21, 2008 at 7:59 AM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org> wrote:
>>> On Thursday 21 February 2008, Lasse Kärkkäinen wrote:
>>>  > The man page says that realloc(ptr, 0) is equivalent to free, even
>>>  > though it isn't. The text on the man page says
>>>  >
>>>  > ---
>>>  > realloc()  changes the size of the memory block pointed to by ptr to
>>>  > size bytes.  The contents will be unchanged to the minimum of the old
>>>  > and new sizes;  newly  allocated memory  will  be  uninitialized.   If
>>>  > ptr  is  NULL,  the call is equivalent to malloc(size); if size is
>>>  > equal to zero, the call is equivalent to free(ptr).  Unless ptr is
>>>  > NULL, it must have been returned by an earlier call to malloc(),
>>>  > calloc() or realloc().  If the area pointed to was moved, a free(ptr)
>>>  > is done. [...]
>>>  > realloc()  returns a pointer to the newly allocated memory, which is
>>>  > suitably aligned for any kind of variable and may be different from
>>>  > ptr, or NULL if the request fails.  If  size  was equal to 0, either
>>>  > NULL or a pointer suitable to be passed to free() is returned.  If
>>>  > realloc() fails the original block is left untouched; it is not freed
>>>  > or moved.
>>>
>>>  i would just word it to say that when realloc() is given a size of 0, it
>>> is implementation defined as to the behavior, but it tends to match the
>>> behavior of malloc(0) (which too is implementation defined).  POSIX and
>>> C99 allow both cases to return either a NULL pointer or a "unique"
>>> pointer.  glibc will return a unique pointer (which cannot actually be
>>> used to store anything), but uClibc may return NULL.
>>>  -mike
>> Lasse, thanks for raising this; Mike, thanks for your input.
>>
>> For man-pages-2.79, I propose to amend the description of realloc() to be:
>>
>>        realloc() changes the size of the memory block pointed to
>>        by  ptr to size bytes.  The contents will be unchanged to
>>        the minimum of the old and  new  sizes;  newly  allocated
>>        memory  will  be uninitialized.  If ptr is NULL, then the
>>        call is equivalent to malloc(size); if size is  equal  to
>>        zero, and ptr is not NULL, then the call is equivalent to
>>        free(ptr).   Unless  ptr  is  NULL,  it  must  have  been
>>        returned  by  an  earlier  call  to malloc(), calloc() or
>>        realloc().  If the area pointed to was moved, a free(ptr)
>>        is done.
> 
> a quick read and it leaves me wondering "what if i call realloc(NULL, 0) ?".  
> if i re-read it a few times, i can work out that the documentation, by not 
> saying anything about size in the first statement, implies that malloc(size) 
> is for all values of size.  but perhaps that should be made explicit ?
> 
> ... If ptr is NULL, then the call is equivalent to malloc(size) for all values 
> of size; ...

Yes, good idea.  I've made that change.

> otherwise, it looks good to me, thanks

Thanks for checking it over.

Cheers,

Michael

-- 
Michael Kerrisk
Maintainer of the Linux man-pages project
http://www.kernel.org/doc/man-pages/
Want to report a man-pages bug?  Look here:
http://www.kernel.org/doc/man-pages/reporting_bugs.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Error in man page: realloc(ptr, 0) is not equivalent to free(ptr)
       [not found]             ` <1203754246.3021.104.camel-DBi1IKlRe8YXiSwHZUBl+UgmxNRb6L7S@public.gmane.org>
  2008-02-23  8:41               ` Mike Frysinger
@ 2008-02-26 15:12               ` Michael Kerrisk
       [not found]                 ` <47C42C68.405-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  1 sibling, 1 reply; 10+ messages in thread
From: Michael Kerrisk @ 2008-02-26 15:12 UTC (permalink / raw)
  To: "Chris \"ク\" Heath"
  Cc: Michael Kerrisk, Mike Frysinger, Lasse Kärkkäinen,
	linux-man-u79uwXL29TY76Z2rM5mHXA

Chris ク Heath wrote:
> On Fri, 2008-02-22 at 11:15 +0100, Michael Kerrisk wrote:
>> On Thu, Feb 21, 2008 at 7:59 AM, Mike Frysinger <vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org> wrote:
>>> On Thursday 21 February 2008, Lasse Kärkkäinen wrote:
>>>  > The man page says that realloc(ptr, 0) is equivalent to free, even
>>>  > though it isn't. The text on the man page says
>>>  >
>>>  > ---
>>>  > realloc()  changes the size of the memory block pointed to by ptr to
>>>  > size bytes.  The contents will be unchanged to the minimum of the old
>>>  > and new sizes;  newly  allocated memory  will  be  uninitialized.   If
>>>  > ptr  is  NULL,  the call is equivalent to malloc(size); if size is equal
>>>  > to zero, the call is equivalent to free(ptr).  Unless ptr is NULL, it
>>>  > must have been returned by an earlier call to malloc(), calloc() or
>>>  > realloc().  If the area pointed to was moved, a free(ptr) is done.
>>>  > [...]
>>>  > realloc()  returns a pointer to the newly allocated memory, which is
>>>  > suitably aligned for any kind of variable and may be different from ptr,
>>>  > or NULL if the request fails.  If  size  was equal to 0, either NULL or
>>>  > a pointer suitable to be passed to free() is returned.  If realloc()
>>>  > fails the original block is left untouched; it is not freed or moved.
>>>
>>>  i would just word it to say that when realloc() is given a size of 0, it is
>>>  implementation defined as to the behavior, but it tends to match the behavior
>>>  of malloc(0) (which too is implementation defined).  POSIX and C99 allow both
>>>  cases to return either a NULL pointer or a "unique" pointer.  glibc will
>>>  return a unique pointer (which cannot actually be used to store anything),
>>>  but uClibc may return NULL.
>>>  -mike
>> Lasse, thanks for raising this; Mike, thanks for your input.
>>
>> For man-pages-2.79, I propose to amend the description of realloc() to be:
>>
>>        realloc() changes the size of the memory block pointed to
>>        by  ptr to size bytes.  The contents will be unchanged to
>>        the minimum of the old and  new  sizes;  newly  allocated
>>        memory  will  be uninitialized.  If ptr is NULL, then the
>>        call is equivalent to malloc(size); if size is  equal  to
>>        zero, and ptr is not NULL, then the call is equivalent to
>>        free(ptr).   Unless  ptr  is  NULL,  it  must  have  been
>>        returned  by  an  earlier  call  to malloc(), calloc() or
>>        realloc().  If the area pointed to was moved, a free(ptr)
>>        is done.
> 
> Hmmm.  The phrase
> 
>                                            if size is  equal  to
>        zero, and ptr is not NULL, then the call is equivalent to
>        free(ptr).
> 
> seems to contradict the following sentence, found under RETURN VALUES:
> 
>                               If size was equal to 0, either NULL
>         or a pointer suitable to be passed to free() is returned.  
> 
> If realloc(ptr, 0) can return a non-NULL pointer, then it isn't
> equivalent to free(ptr).
> 
> So which one is correct?  My tests with glibc 2.6 indicate that
> realloc(ptr, 0) always returns NULL, so it IS equivalent to free(ptr).
> However, I don't know if that is guaranteed to always be the case.

Chris,

The text under RETURN VALUE is quite close to the POSIX.1 spec for
realloc(), which says this:

       If size is 0, either a null pointer or a
       unique pointer that can be successfully passed to  free()
       shall be returned.

After Mike's last suggestion, the body of the Linux man page says this:

       If ptr is NULL, then the
       call is equivalent to malloc(size),  for  all  values  of
       size; if size is equal to zero, and ptr is not NULL, then
       the call is equivalent to free(ptr).

So:

a) If ptr is NULL, and size is zero, then realloc() is equivalent to
malloc(0), which does the following (as already documented in the Linux
malloc.3 man page):

       If size is 0, then malloc() returns either NULL, or a unique
       pointer value that can later be successfully passed to free().

That seems entirely consistent with the text under RETURN VALUE for the
Linux malloc.3 man page.

b) If ptr is not NULL, and size is zero, then the standard isn't (AFAICS)
explicit about whether "a null pointer or a unique pointer that can be
successfully passed to free()" shall be returned, but the former certainly
seems more reasonable, and is what you observed for glibc.

Cheers,

Michael

-- 
Michael Kerrisk
Maintainer of the Linux man-pages project
http://www.kernel.org/doc/man-pages/
Want to report a man-pages bug?  Look here:
http://www.kernel.org/doc/man-pages/reporting_bugs.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Error in man page: realloc(ptr, 0) is not equivalent to free(ptr)
       [not found]                 ` <47C42C68.405-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2008-03-02 13:01                   ` Michael Kerrisk
       [not found]                     ` <cfd18e0f0803020501y4e803b6dk5479db1f1f36b37-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 10+ messages in thread
From: Michael Kerrisk @ 2008-03-02 13:01 UTC (permalink / raw)
  To: "Chris \"ク\" Heath"
  Cc: Michael Kerrisk, Mike Frysinger, Lasse Kärkkäinen,
	linux-man-u79uwXL29TY76Z2rM5mHXA

Chris,

Ping!  Did you have anything further to add?

Cheers,

Michael

On Tue, Feb 26, 2008 at 4:12 PM, Michael Kerrisk
<mtk.manpages@googlemail.com> wrote:
>
> Chris ク Heath wrote:
> > On Fri, 2008-02-22 at 11:15 +0100, Michael Kerrisk wrote:
> >> On Thu, Feb 21, 2008 at 7:59 AM, Mike Frysinger <vapier@gentoo.org> wrote:
> >>> On Thursday 21 February 2008, Lasse Kärkkäinen wrote:
> >>>  > The man page says that realloc(ptr, 0) is equivalent to free, even
> >>>  > though it isn't. The text on the man page says
> >>>  >
> >>>  > ---
> >>>  > realloc()  changes the size of the memory block pointed to by ptr to
> >>>  > size bytes.  The contents will be unchanged to the minimum of the old
> >>>  > and new sizes;  newly  allocated memory  will  be  uninitialized.   If
> >>>  > ptr  is  NULL,  the call is equivalent to malloc(size); if size is equal
> >>>  > to zero, the call is equivalent to free(ptr).  Unless ptr is NULL, it
> >>>  > must have been returned by an earlier call to malloc(), calloc() or
> >>>  > realloc().  If the area pointed to was moved, a free(ptr) is done.
> >>>  > [...]
> >>>  > realloc()  returns a pointer to the newly allocated memory, which is
> >>>  > suitably aligned for any kind of variable and may be different from ptr,
> >>>  > or NULL if the request fails.  If  size  was equal to 0, either NULL or
> >>>  > a pointer suitable to be passed to free() is returned.  If realloc()
> >>>  > fails the original block is left untouched; it is not freed or moved.
> >>>
> >>>  i would just word it to say that when realloc() is given a size of 0, it is
> >>>  implementation defined as to the behavior, but it tends to match the behavior
> >>>  of malloc(0) (which too is implementation defined).  POSIX and C99 allow both
> >>>  cases to return either a NULL pointer or a "unique" pointer.  glibc will
> >>>  return a unique pointer (which cannot actually be used to store anything),
> >>>  but uClibc may return NULL.
> >>>  -mike
> >> Lasse, thanks for raising this; Mike, thanks for your input.
> >>
> >> For man-pages-2.79, I propose to amend the description of realloc() to be:
> >>
> >>        realloc() changes the size of the memory block pointed to
> >>        by  ptr to size bytes.  The contents will be unchanged to
> >>        the minimum of the old and  new  sizes;  newly  allocated
> >>        memory  will  be uninitialized.  If ptr is NULL, then the
> >>        call is equivalent to malloc(size); if size is  equal  to
> >>        zero, and ptr is not NULL, then the call is equivalent to
> >>        free(ptr).   Unless  ptr  is  NULL,  it  must  have  been
> >>        returned  by  an  earlier  call  to malloc(), calloc() or
> >>        realloc().  If the area pointed to was moved, a free(ptr)
> >>        is done.
> >
> > Hmmm.  The phrase
> >
> >                                            if size is  equal  to
> >        zero, and ptr is not NULL, then the call is equivalent to
> >        free(ptr).
> >
> > seems to contradict the following sentence, found under RETURN VALUES:
> >
> >                               If size was equal to 0, either NULL
> >         or a pointer suitable to be passed to free() is returned.
> >
> > If realloc(ptr, 0) can return a non-NULL pointer, then it isn't
> > equivalent to free(ptr).
> >
> > So which one is correct?  My tests with glibc 2.6 indicate that
> > realloc(ptr, 0) always returns NULL, so it IS equivalent to free(ptr).
> > However, I don't know if that is guaranteed to always be the case.
>
> Chris,
>
> The text under RETURN VALUE is quite close to the POSIX.1 spec for
> realloc(), which says this:
>
>       If size is 0, either a null pointer or a
>       unique pointer that can be successfully passed to  free()
>       shall be returned.
>
> After Mike's last suggestion, the body of the Linux man page says this:
>
>       If ptr is NULL, then the
>       call is equivalent to malloc(size),  for  all  values  of
>       size; if size is equal to zero, and ptr is not NULL, then
>       the call is equivalent to free(ptr).
>
> So:
>
> a) If ptr is NULL, and size is zero, then realloc() is equivalent to
> malloc(0), which does the following (as already documented in the Linux
> malloc.3 man page):
>
>       If size is 0, then malloc() returns either NULL, or a unique
>       pointer value that can later be successfully passed to free().
>
> That seems entirely consistent with the text under RETURN VALUE for the
> Linux malloc.3 man page.
>
> b) If ptr is not NULL, and size is zero, then the standard isn't (AFAICS)
> explicit about whether "a null pointer or a unique pointer that can be
> successfully passed to free()" shall be returned, but the former certainly
> seems more reasonable, and is what you observed for glibc.
>
>
> Cheers,
>
> Michael
>
> --
> Michael Kerrisk
> Maintainer of the Linux man-pages project
> http://www.kernel.org/doc/man-pages/
> Want to report a man-pages bug?  Look here:
> http://www.kernel.org/doc/man-pages/reporting_bugs.html
>
>
>



-- 
Michael Kerrisk
Maintainer of the Linux man-pages project
http://www.kernel.org/doc/man-pages/
Want to report a man-pages bug?  Look here:
http://www.kernel.org/doc/man-pages/reporting_bugs.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Error in man page: realloc(ptr, 0) is not equivalent to free(ptr)
       [not found]                     ` <cfd18e0f0803020501y4e803b6dk5479db1f1f36b37-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2008-03-02 23:53                       ` Chris "ク" Heath
  0 siblings, 0 replies; 10+ messages in thread
From: Chris "ク" Heath @ 2008-03-02 23:53 UTC (permalink / raw)
  To: Michael Kerrisk
  Cc: Mike Frysinger, Lasse Kärkkäinen,
	linux-man-u79uwXL29TY76Z2rM5mHXA

On Sun, 2008-03-02 at 14:01 +0100, Michael Kerrisk wrote:
> Chris,
> 
> Ping!  Did you have anything further to add?

I stopped following this thread because I realized that my main issue
was with the standards.

I have one comment though:  I believe that the ISO C standard mandates
that, for ptr != NULL, realloc(ptr,0) be equivalent to free() (and
return NULL), whereas POSIX uses the vaguer phrase "pointer is
freed" (and return a null pointer or a unique pointer that can be
successfully passed to free()).

The man-page is mixing the two standards, saying it is equivalent to
free() but returns a null pointer or a unique pointer that can be
successfully passed to free().  While this is technically correct, it is
less internally consistent than either of the standards.  How about
following POSIX and using "ptr is freed" instead of "equivalent to
free(ptr)"?

Chris


> Cheers,
> 
> Michael
> 
> On Tue, Feb 26, 2008 at 4:12 PM, Michael Kerrisk
> <mtk.manpages-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:
> >
> > Chris ク Heath wrote:
> > > On Fri, 2008-02-22 at 11:15 +0100, Michael Kerrisk wrote:
> > >> On Thu, Feb 21, 2008 at 7:59 AM, Mike Frysinger <vapier@gentoo.org> wrote:
> > >>> On Thursday 21 February 2008, Lasse Kärkkäinen wrote:
> > >>>  > The man page says that realloc(ptr, 0) is equivalent to free, even
> > >>>  > though it isn't. The text on the man page says
> > >>>  >
> > >>>  > ---
> > >>>  > realloc()  changes the size of the memory block pointed to by ptr to
> > >>>  > size bytes.  The contents will be unchanged to the minimum of the old
> > >>>  > and new sizes;  newly  allocated memory  will  be  uninitialized.   If
> > >>>  > ptr  is  NULL,  the call is equivalent to malloc(size); if size is equal
> > >>>  > to zero, the call is equivalent to free(ptr).  Unless ptr is NULL, it
> > >>>  > must have been returned by an earlier call to malloc(), calloc() or
> > >>>  > realloc().  If the area pointed to was moved, a free(ptr) is done.
> > >>>  > [...]
> > >>>  > realloc()  returns a pointer to the newly allocated memory, which is
> > >>>  > suitably aligned for any kind of variable and may be different from ptr,
> > >>>  > or NULL if the request fails.  If  size  was equal to 0, either NULL or
> > >>>  > a pointer suitable to be passed to free() is returned.  If realloc()
> > >>>  > fails the original block is left untouched; it is not freed or moved.
> > >>>
> > >>>  i would just word it to say that when realloc() is given a size of 0, it is
> > >>>  implementation defined as to the behavior, but it tends to match the behavior
> > >>>  of malloc(0) (which too is implementation defined).  POSIX and C99 allow both
> > >>>  cases to return either a NULL pointer or a "unique" pointer.  glibc will
> > >>>  return a unique pointer (which cannot actually be used to store anything),
> > >>>  but uClibc may return NULL.
> > >>>  -mike
> > >> Lasse, thanks for raising this; Mike, thanks for your input.
> > >>
> > >> For man-pages-2.79, I propose to amend the description of realloc() to be:
> > >>
> > >>        realloc() changes the size of the memory block pointed to
> > >>        by  ptr to size bytes.  The contents will be unchanged to
> > >>        the minimum of the old and  new  sizes;  newly  allocated
> > >>        memory  will  be uninitialized.  If ptr is NULL, then the
> > >>        call is equivalent to malloc(size); if size is  equal  to
> > >>        zero, and ptr is not NULL, then the call is equivalent to
> > >>        free(ptr).   Unless  ptr  is  NULL,  it  must  have  been
> > >>        returned  by  an  earlier  call  to malloc(), calloc() or
> > >>        realloc().  If the area pointed to was moved, a free(ptr)
> > >>        is done.
> > >
> > > Hmmm.  The phrase
> > >
> > >                                            if size is  equal  to
> > >        zero, and ptr is not NULL, then the call is equivalent to
> > >        free(ptr).
> > >
> > > seems to contradict the following sentence, found under RETURN VALUES:
> > >
> > >                               If size was equal to 0, either NULL
> > >         or a pointer suitable to be passed to free() is returned.
> > >
> > > If realloc(ptr, 0) can return a non-NULL pointer, then it isn't
> > > equivalent to free(ptr).
> > >
> > > So which one is correct?  My tests with glibc 2.6 indicate that
> > > realloc(ptr, 0) always returns NULL, so it IS equivalent to free(ptr).
> > > However, I don't know if that is guaranteed to always be the case.
> >
> > Chris,
> >
> > The text under RETURN VALUE is quite close to the POSIX.1 spec for
> > realloc(), which says this:
> >
> >       If size is 0, either a null pointer or a
> >       unique pointer that can be successfully passed to  free()
> >       shall be returned.
> >
> > After Mike's last suggestion, the body of the Linux man page says this:
> >
> >       If ptr is NULL, then the
> >       call is equivalent to malloc(size),  for  all  values  of
> >       size; if size is equal to zero, and ptr is not NULL, then
> >       the call is equivalent to free(ptr).
> >
> > So:
> >
> > a) If ptr is NULL, and size is zero, then realloc() is equivalent to
> > malloc(0), which does the following (as already documented in the Linux
> > malloc.3 man page):
> >
> >       If size is 0, then malloc() returns either NULL, or a unique
> >       pointer value that can later be successfully passed to free().
> >
> > That seems entirely consistent with the text under RETURN VALUE for the
> > Linux malloc.3 man page.
> >
> > b) If ptr is not NULL, and size is zero, then the standard isn't (AFAICS)
> > explicit about whether "a null pointer or a unique pointer that can be
> > successfully passed to free()" shall be returned, but the former certainly
> > seems more reasonable, and is what you observed for glibc.
> >
> >
> > Cheers,
> >
> > Michael
> >
> > --
> > Michael Kerrisk
> > Maintainer of the Linux man-pages project
> > http://www.kernel.org/doc/man-pages/
> > Want to report a man-pages bug?  Look here:
> > http://www.kernel.org/doc/man-pages/reporting_bugs.html
> >
> >
> >
> 
> 
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2008-03-02 23:53 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-21  6:26 Error in man page: realloc(ptr, 0) is not equivalent to free(ptr) Lasse Kärkkäinen
     [not found] ` <47BD19AF.4000101-ze05kZMmeybHOG6cAo2yLw@public.gmane.org>
2008-02-21  6:59   ` Mike Frysinger
     [not found]     ` <200802210159.03465.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
2008-02-22 10:15       ` Michael Kerrisk
     [not found]         ` <cfd18e0f0802220215l6e61ab90h4a2d9b2e3e2a194d-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-02-23  6:38           ` Mike Frysinger
     [not found]             ` <200802230138.11461.vapier-aBrp7R+bbdUdnm+yROfE0A@public.gmane.org>
2008-02-26 15:12               ` Michael Kerrisk
2008-02-23  8:10           ` Chris "ク" Heath
     [not found]             ` <1203754246.3021.104.camel-DBi1IKlRe8YXiSwHZUBl+UgmxNRb6L7S@public.gmane.org>
2008-02-23  8:41               ` Mike Frysinger
2008-02-26 15:12               ` Michael Kerrisk
     [not found]                 ` <47C42C68.405-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2008-03-02 13:01                   ` Michael Kerrisk
     [not found]                     ` <cfd18e0f0803020501y4e803b6dk5479db1f1f36b37-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-03-02 23:53                       ` Chris "ク" Heath

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox