realloc() to zero size

Discussion in 'C Programming' started by Kenneth Brody, Aug 20, 2007.

  1. I looked at my copy of n1124, and I didn't see anything about this
    particular situation...

    What happens if you realloc() to a size of zero?

    Implementations are allowed to return NULL on malloc(0), and realloc()
    says it reutrns NULL on failure. (And, on failure, the old pointer
    has not been freed.)

    Is it possible for an implementation to return NULL for realloc(ptr,0)
    and have the old buffer freed?

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Aug 20, 2007
    #1
    1. Advertising

  2. Kenneth Brody wrote:
    > I looked at my copy of n1124, and I didn't see anything about this
    > particular situation...
    >
    > What happens if you realloc() to a size of zero?
    >
    > Implementations are allowed to return NULL on malloc(0), and realloc()
    > says it reutrns NULL on failure. (And, on failure, the old pointer
    > has not been freed.)
    >
    > Is it possible for an implementation to return NULL for realloc(ptr,0)
    > and have the old buffer freed?


    In C99, no. realloc differs from malloc in that is specified as returning
    either a pointer to a new object, or a null pointer if the new object could
    not be allocated. A null pointer is not a pointer to an object, so can only
    indicate allocation failure, and on allocation failure, the old buffer is
    not freed. In C90, however, realloc(p, 0) unconditionally frees p,
    regardless of whether it returns a null pointer. There was a thread on
    comp.std.c about it a while ago:

    http://groups.google.com/group/comp.std.c/browse_thread/thread/6355064cb8f54637/
     
    Harald van =?UTF-8?B?RMSzaw==?=, Aug 20, 2007
    #2
    1. Advertising

  3. Kenneth Brody <> writes:
    > I looked at my copy of n1124, and I didn't see anything about this
    > particular situation...
    >
    > What happens if you realloc() to a size of zero?
    >
    > Implementations are allowed to return NULL on malloc(0), and realloc()
    > says it reutrns NULL on failure. (And, on failure, the old pointer
    > has not been freed.)
    >
    > Is it possible for an implementation to return NULL for realloc(ptr,0)
    > and have the old buffer freed?


    realloc with a size of 0 behaves similarly to malloc(0). This is
    explained in 7.20.3p1, at the top of the "Memory management
    functions", not in the documentation of realloc itself; it applies to
    malloc, calloc, and realloc.

    As for malloc, though, if a call with a size of 0 returns a null
    pointer, you can't tell whether it succeeded or failed. So given:

    ptr1 = malloc(42);
    assert(ptr != NULL);
    ptr2 = realloc(ptr, 0);

    if ptr2 == NULL, it could be either because it failed (in which case
    ptr1 still points to the originally allocated memory) or because it
    succeeded (in which case the memory has been deallocated and ptr1 has
    an indeterminate value).

    But that seems to be inconsistent with the description if realloc
    itself in 7.20.3.4p4:

    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.

    I'd try to avoid calling realloc with a size of 0.

    Unless somebody can come up with an analysis that settles this, I'll
    probably post to comp.std.c.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Aug 20, 2007
    #3
  4. Harald van Dijk <> writes:
    > Kenneth Brody wrote:
    >> I looked at my copy of n1124, and I didn't see anything about this
    >> particular situation...
    >>
    >> What happens if you realloc() to a size of zero?
    >>
    >> Implementations are allowed to return NULL on malloc(0), and realloc()
    >> says it reutrns NULL on failure. (And, on failure, the old pointer
    >> has not been freed.)
    >>
    >> Is it possible for an implementation to return NULL for realloc(ptr,0)
    >> and have the old buffer freed?

    >
    > In C99, no. realloc differs from malloc in that is specified as returning
    > either a pointer to a new object, or a null pointer if the new object could
    > not be allocated. A null pointer is not a pointer to an object, so can only
    > indicate allocation failure, and on allocation failure, the old buffer is
    > not freed. In C90, however, realloc(p, 0) unconditionally frees p,
    > regardless of whether it returns a null pointer. There was a thread on
    > comp.std.c about it a while ago:
    >
    > http://groups.google.com/group/comp.std.c/browse_thread/thread/6355064cb8f54637/


    I just re-read that thread (and I even participated in it), but I
    don't think it actually settled the issue.

    I still see a contradiction between C99 7.20.3.1p1, which applies to
    malloc, calloc, and realloc:

    If the space cannot be allocated, a null pointer is returned. If
    the size of the space requested is zero, the behavior is
    implementation-defined: either a null pointer is returned, or the
    behavior is as if the size were some nonzero value, except that
    the returned pointer shall not be used to access an object.

    (which allows realloc(non_null, 0) to return either a null pointer or
    a non-null pointer, and doesn't allow you to determine whether it
    succeeded or failed if it returns a null pointer), and C99 7.20.3.4p4,
    which applies only to realloc:

    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.

    (which *doesn't* allow realloc(non_null, 0) to return a null pointer
    unless the allocation actually fails).

    An implementation can obey both by having all three *alloc functions
    with a zero size argument return a null pointer *only* on failure.
    The question is whether an implementation of realloc that returns a
    null pointer for a zero size argument even on success is conforming.
    My impression is that the authors of C99 cleaned up the description of
    realloc, but neglected to go back and clean up the earlier description
    that applies to all three allocation functions.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Aug 20, 2007
    #4
  5. Keith Thompson wrote:
    > Harald van Dijk <> writes:
    >> Kenneth Brody wrote:
    >>> I looked at my copy of n1124, and I didn't see anything about this
    >>> particular situation...
    >>>
    >>> What happens if you realloc() to a size of zero?
    >>>
    >>> Implementations are allowed to return NULL on malloc(0), and realloc()
    >>> says it reutrns NULL on failure. (And, on failure, the old pointer
    >>> has not been freed.)
    >>>
    >>> Is it possible for an implementation to return NULL for realloc(ptr,0)
    >>> and have the old buffer freed?

    >>
    >> In C99, no. realloc differs from malloc in that is specified as returning
    >> either a pointer to a new object, or a null pointer if the new object
    >> could not be allocated. A null pointer is not a pointer to an object, so
    >> can only indicate allocation failure, and on allocation failure, the old
    >> buffer is not freed. In C90, however, realloc(p, 0) unconditionally frees
    >> p, regardless of whether it returns a null pointer. There was a thread on
    >> comp.std.c about it a while ago:
    >>
    >>

    http://groups.google.com/group/comp.std.c/browse_thread/thread/6355064cb8f54637/
    >
    > I just re-read that thread (and I even participated in it), but I
    > don't think it actually settled the issue.


    FWIW, the original question was settled well enough for Mr. Furuseth, and
    also for myself. Doug Gwyn's arguments were pretty convincing.

    > I still see a contradiction between C99 7.20.3.1p1, which applies to
    > malloc, calloc, and realloc:


    That's 7.20.3p1, actually. :)

    > If the space cannot be allocated, a null pointer is returned. If
    > the size of the space requested is zero, the behavior is
    > implementation-defined: either a null pointer is returned, or the
    > behavior is as if the size were some nonzero value, except that
    > the returned pointer shall not be used to access an object.
    >
    > (which allows realloc(non_null, 0) to return either a null pointer or
    > a non-null pointer, and doesn't allow you to determine whether it
    > succeeded or failed if it returns a null pointer), and C99 7.20.3.4p4,
    > which applies only to realloc:
    >
    > 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.
    >
    > (which *doesn't* allow realloc(non_null, 0) to return a null pointer
    > unless the allocation actually fails).
    >
    > An implementation can obey both by having all three *alloc functions
    > with a zero size argument return a null pointer *only* on failure.


    And as both paragraphs are normative, an implementation must obey both.

    > The question is whether an implementation of realloc that returns a
    > null pointer for a zero size argument even on success is conforming.


    If realloc(p, 0) frees p and returns a null pointer, the implementation
    violates 7.20.3.4p3-4, so it cannot claim conformance to C99.

    7.20.3p1 allows malloc(0) and realloc(p, 0) to return a null pointer, but
    does not specify whether this indicates success or failure. In the case of
    malloc, it makes no difference. In the case of realloc, 7.20.3.4p4
    specifies that it signals a failure, and 7.20.3.4p3 specifies that because
    of it, the old object is not freed.

    > My impression is that the authors of C99 cleaned up the description of
    > realloc, but neglected to go back and clean up the earlier description
    > that applies to all three allocation functions.


    That's very well possible; the current wording is certainly confusing at the
    least.
     
    Harald van =?UTF-8?B?RMSzaw==?=, Aug 20, 2007
    #5
  6. Groovy hepcat Kenneth Brody was jivin' in comp.lang.c on Tue, 21 Aug
    2007 3:43 am. It's a cool scene! Dig it.

    > I looked at my copy of n1124, and I didn't see anything about this
    > particular situation...
    >
    > What happens if you realloc() to a size of zero?
    >
    > Implementations are allowed to return NULL on malloc(0), and realloc()
    > says it reutrns NULL on failure. (And, on failure, the old pointer
    > has not been freed.)
    >
    > Is it possible for an implementation to return NULL for realloc(ptr,0)
    > and have the old buffer freed?


    It's the same for calloc(), malloc() and realloc(). See the exerpt
    below.

    -----------------------------------------------------------------------
    7.20.3 Memory management functions

    1 ... If the size of the space requested is zero, the behavior is
    implementation defined: either a null pointer is returned, or the
    behavior is as if the size were some nonzero value, except that the
    returned pointer shall not be used to access an object.
    -----------------------------------------------------------------------

    --
    Dig the sig!

    ----------- Peter 'Shaggy' Haywood ------------
    Ain't I'm a dawg!!
     
    Peter 'Shaggy' Haywood, Aug 25, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Zhiqiang Ye
    Replies:
    53
    Views:
    10,420
    Dan Pop
    Jun 28, 2004
  2. Gerard Flanagan
    Replies:
    3
    Views:
    498
    Terry Hancock
    Nov 19, 2005
  3. Christopher Benson-Manica

    Doubles and zero/negative zero

    Christopher Benson-Manica, Jun 30, 2004, in forum: C Programming
    Replies:
    4
    Views:
    719
    Walter
    Jul 1, 2004
  4. Deephay

    realloc(): invalid next size

    Deephay, Apr 11, 2006, in forum: C Programming
    Replies:
    27
    Views:
    8,521
    Rod Pemberton
    Apr 14, 2006
  5. Robert Seacord

    realloc zero bytes?

    Robert Seacord, Jan 9, 2007, in forum: C Programming
    Replies:
    64
    Views:
    1,444
    Flash Gordon
    Jan 22, 2007
Loading...

Share This Page