Is this correct according to C coding standards?

Discussion in 'C Programming' started by s.subbarayan, Mar 8, 2005.

  1. s.subbarayan

    s.subbarayan Guest

    Dear all,
    In one of our projects in a document about C coding standard it is
    stated as
    "Always check a pointer is NULL before calling free. Always set a
    free'd pointer to NULL to try to protect it from being used again
    later and causing memory leaks."

    My doubt is,"Is this standard practice every where?"Also is it valid
    to free a pointer after the value is set to NULL?Because AFAIK,NULL
    means it points to nowhere!

    Another doubt in the similar manner:I am not able to understand the
    behaviour of this code:

    char *ptr;
    if ((ptr = (char *)malloc(0)) ==
    NULL)
    puts("Got a null pointer");
    else
    puts("Got a valid pointer");


    This piece of code gives "Got a valid pointer".How come when I specify
    a size of zero,memory is allocated and ptr becomes a valid pointer?
    I am not able to get the proper reason ,can anyone enlighten me the
    reason behind this?

    Looking farward for all your replys and advanced thanks for the same,
    Regards,
    s.subbarayan
     
    s.subbarayan, Mar 8, 2005
    #1
    1. Advertising

  2. (s.subbarayan) writes:
    > In one of our projects in a document about C coding standard it is
    > stated as
    > "Always check a pointer is NULL before calling free. Always set a
    > free'd pointer to NULL to try to protect it from being used again
    > later and causing memory leaks."
    >
    > My doubt is,"Is this standard practice every where?"Also is it valid
    > to free a pointer after the value is set to NULL?Because AFAIK,NULL
    > means it points to nowhere!
    >
    > Another doubt in the similar manner:I am not able to understand the
    > behaviour of this code:
    >
    > char *ptr;
    > if ((ptr = (char *)malloc(0)) ==
    > NULL)
    > puts("Got a null pointer");
    > else
    > puts("Got a valid pointer");


    The cast is superfluous; you can change
    ptr = (char *)malloc(0)
    to
    ptr = malloc(0)
    malloc() returns a pointer to void, which is implicitly converted to
    whatever pointer type you assign it to. But that's a minor point.

    > This piece of code gives "Got a valid pointer".How come when I specify
    > a size of zero,memory is allocated and ptr becomes a valid pointer?
    > I am not able to get the proper reason ,can anyone enlighten me the
    > reason behind this?


    Here's what the standard says:

    For 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.

    For free()

    The free function causes the space pointed to by ptr to be
    deallocated, that is, made available for further allocation. If
    ptr is a null pointer, no action occurs.

    There's no need to check whether a pointer is null before calling
    free; free(NULL) is perfectly valid, and does nothing. (There may be
    some very old pre-ANSI implementations that misbehave on free(NULL).
    There's usually no need for coding standards to cater to such
    implementations.)

    Setting a pointer to NULL after freeing it:
    free(ptr);
    ptr = NULL;
    provides some slight protection, but it's not absolute. For example:
    ptr = malloc(whatever);
    another_ptr = ptr;
    free(ptr);
    ptr = NULL;
    Here I've set ptr to NULL, but another_ptr still contains a copy of
    the (now invalid) pointer value. I won't argue that you *shouldn't*
    set the pointer to NULL, but don't expect it to catch all your errors;
    there's no substitute for careful programming that avoids referring to
    free()d pointers.

    As for malloc(0), it can return either a null pointer or a valid
    pointer (though one that's not particularly useful). If your program
    might call malloc() with an argument of 0, you'll need to deal with
    both possibilities.

    --
    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.
     
    Keith Thompson, Mar 8, 2005
    #2
    1. Advertising

  3. s.subbarayan wrote:

    >Dear all,
    > In one of our projects in a document about C coding standard it is
    >stated as
    >"Always check a pointer is NULL before calling free. Always set a
    >
    >

    Redundant. free on null pointer is well defined by standard(no action
    occurs).

    >free'd pointer to NULL to try to protect it from being used again
    >later and causing memory leaks."
    >
    >

    Setting a pointer to null after free is a good idea as it eliminates the
    possibilty of free memory read.

    >My doubt is,"Is this standard practice every where?"Also is it valid
    >to free a pointer after the value is set to NULL?Because AFAIK,NULL
    >means it points to nowhere!
    >
    >Another doubt in the similar manner:I am not able to understand the
    >behaviour of this code:
    >
    >char *ptr;
    >if ((ptr = (char *)malloc(0)) ==
    > NULL)
    > puts("Got a null pointer");
    >else
    > puts("Got a valid pointer");
    >
    >
    >This piece of code gives "Got a valid pointer".How come when I specify
    >a size of zero,memory is allocated and ptr becomes a valid pointer?
    >I am not able to get the proper reason ,can anyone enlighten me the
    >reason behind this?
    >
    >
    >

    Already in FAQ

    http://www.eskimo.com/~scs/C-faq/q11.26.html

    Krishanu
     
    Krishanu Debnath, Mar 8, 2005
    #3
  4. s.subbarayan

    Quentarez Guest

    On 8 Mar 2005 02:18:13 -0800, s.subbarayan wrote:

    > Dear all,
    > In one of our projects in a document about C coding standard it is
    > stated as
    > "Always check a pointer is NULL before calling free. Always set a
    > free'd pointer to NULL to try to protect it from being used again
    > later and causing memory leaks."
    >

    <snip>

    The purpose of free() is to deallocate memory that was allocated by any of
    the allocation functions. If you do this:

    char *p = malloc(n);
    if (p != NULL)
    {
    p = NULL;
    }
    free(p);

    you have just leaked memory. Your pointer needs to be pointing to what you
    want to free when you free it. If your pointer is null when passed to free,
    free will do nothing. After you have free'd your memory (properly), it is
    considered good practice to set the pointer to NULL for future error
    checking, just to make sure you don't use an invalid pointer.

    > Another doubt in the similar manner:I am not able to understand the
    > behaviour of this code:
    >
    > char *ptr;
    > if ((ptr = (char *)malloc(0)) ==
    > NULL)
    > puts("Got a null pointer");
    > else
    > puts("Got a valid pointer");
    >
    >

    <snip>

    In the case of:

    char *p = malloc(0);

    malloc has two choices: either it can return a non-null pointer which you
    can not dereference, or it can return NULL. It is up to malloc to decide
    which to return.
     
    Quentarez, Mar 8, 2005
    #4
  5. s.subbarayan

    -berlin.de Guest

    s.subbarayan <> wrote:
    > In one of our projects in a document about C coding standard it is
    > stated as
    > "Always check a pointer is NULL before calling free. Always set a
    > free'd pointer to NULL to try to protect it from being used again
    > later and causing memory leaks."


    > My doubt is,"Is this standard practice every where?"Also is it valid
    > to free a pointer after the value is set to NULL?Because AFAIK,NULL
    > means it points to nowhere!


    I don't know if this standard practice everywhere since I don't know
    everywhere;-). But since calling free() on a NULL pointer is legal
    (it is a no-op) I don't really see what it's meant to be good for.
    On the other hand, setting a free()ed pointer to NULL is a quite
    common practise that can help to find bugs where it is attempted to
    use already free()ed memory, i.e. memory you don't own anymore - if
    you set a pointer to NULL after free()ing what it was pointing to
    the program will crash immediately when you try to dereference the
    pointer, giving a clear indication that something is badly broken.
    Of course, that's not a silver bullet since other pointers may still
    exist also pointing to the free()ed memory region which you won't
    find that way...

    > Another doubt in the similar manner:I am not able to understand the
    > behaviour of this code:


    > char *ptr;
    > if ((ptr = (char *)malloc(0)) ==
    > NULL)
    > puts("Got a null pointer");
    > else
    > puts("Got a valid pointer");


    > This piece of code gives "Got a valid pointer".How come when I specify
    > a size of zero,memory is allocated and ptr becomes a valid pointer?


    There's no memory allocated in that case. You only get a pointer but
    with no memory attached to it you could really use. The pointer can
    only be used as an argument in calls of free() or realloc().

    > I am not able to get the proper reason ,can anyone enlighten me the
    > reason behind this?


    I guess the rationale behind this is symmetry with realloc(). When you
    call realloc() with a valid pointer but a zero size it frees the memory
    the pointer was pointing to - but in this case realloc() can't return a
    NULL pointer since that would make the return value indistinguishable
    from a failure. So realloc() must free() the memory but return the
    pointer it was called with also in this case. And malloc() obviously
    mimics this behavior to make things as similar as possible, allowing
    you to use one function in place of the other in many places, which
    can often make things quit a bit simpler.

    Regards, Jens
    --
    \ Jens Thoms Toerring ___ -berlin.de
    \__________________________ http://www.toerring.de
     
    -berlin.de, Mar 8, 2005
    #5
  6. On Tue, 08 Mar 2005 02:18:13 -0800, s.subbarayan wrote:

    > Dear all,
    > In one of our projects in a document about C coding standard it is
    > stated as
    > "Always check a pointer is NULL before calling free.


    This used to be a sensible thing to do. However since C was first
    standardised in 1989 free() has been specified to do nothing when passed a
    null pointer. 15+ years on it is reasonable to assume that all compilers
    you are likely to meet will implement this behaviour. Only worry about
    this if you know you will have to use a VERY old compiler.

    > Always set a
    > free'd pointer to NULL to try to protect it from being used again
    > later and causing memory leaks."


    This won't protect against memory leaks i.e. failing to free unused memory
    in the first place. It also doesn't provide the other protection stated
    because you would have to set ALL pointers into that block of memory to
    null not just the one that happens to be being used to pass a value to
    free(). Where the null pointer is meaningful (e.g. at a terminal node in
    some datastructure) then setting it to null when it no longer points at
    anything is vital. When the pointer should simply never be used again
    after then free() call then simply make sure you don't use it again. E.g.
    if you free() a pointer that is a local automatic function variable then
    shortly after return from the function there is no value in setting the
    pointer to null.

    > My doubt is,"Is this standard practice every where?


    There are very few if any coding standards that are standard practice
    "everywhere".

    > "Also is it valid to
    > free a pointer after the value is set to NULL?Because AFAIK,NULL means
    > it points to nowhere!


    As noted above free() is well defined when passed a null pointer, it does
    nothing.

    > Another doubt in the similar manner:I am not able to understand the
    > behaviour of this code:
    >
    > char *ptr;
    > if ((ptr = (char *)malloc(0)) ==
    > NULL)
    > puts("Got a null pointer");
    > else
    > puts("Got a valid pointer");
    >
    >
    > This piece of code gives "Got a valid pointer".How come when I specify a
    > size of zero,memory is allocated and ptr becomes a valid pointer? I am
    > not able to get the proper reason ,can anyone enlighten me the reason
    > behind this?


    The reason is that the standad says it can. It can also return a null
    pointer. Of course malloc() is always at liberty to return a null
    pointer, but some implementations will always do so when malloc() is
    passed 0.

    Lawrence
     
    Lawrence Kirby, Mar 8, 2005
    #6
  7. s.subbarayan

    CBFalconer Guest

    "s.subbarayan" wrote:
    >
    > In one of our projects in a document about C coding standard it is
    > stated as
    > "Always check a pointer is NULL before calling free. Always set a
    > free'd pointer to NULL to try to protect it from being used again
    > later and causing memory leaks."
    >
    > My doubt is,"Is this standard practice every where?" Also is it
    > valid to free a pointer after the value is set to NULL? Because
    > AFAIK,NULL means it points to nowhere!


    Above edited to insert blanks at the end of sentences, and make it
    readable. The blank shortage is over. There is no reason to
    obfuscate your article, especially if one of your objectives is to
    get people to read it.

    It is valid to pass NULL to free, because the standard specifically
    says so. Re-freeing a pointer does not cause a memory leak, it
    causes undefined behaviour, and often a crash. Thus the ability to
    free(NULL) is convenient.

    >
    > Another doubt in the similar manner: I am not able to understand the
    > behaviour of this code:
    >
    > char *ptr;
    > if ((ptr = (char *)malloc(0)) == NULL)
    > puts("Got a null pointer");
    > else
    > puts("Got a valid pointer");


    Get rid of the cast. All it does is inhibit warnings.

    >
    > This piece of code gives "Got a valid pointer". How come when I
    > specify a size of zero, memory is allocated and ptr becomes a
    > valid pointer? I am not able to get the proper reason, can
    > anyone enlighten me the reason behind this?


    See above on the care and feeding of blanks. Once more, the
    pointer is valid because the standard says it must be. It can't be
    dereferenced because no valid object can occupy zero bytes. It is
    up to the implementor to meet these criteria.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
     
    CBFalconer, Mar 8, 2005
    #7
  8. s.subbarayan

    pete Guest

    CBFalconer wrote:
    >
    > "s.subbarayan" wrote:
    > >


    > > Another doubt in the similar manner: I am not able to understand the
    > > behaviour of this code:
    > >
    > > char *ptr;
    > > if ((ptr = (char *)malloc(0)) == NULL)
    > > puts("Got a null pointer");
    > > else
    > > puts("Got a valid pointer");

    >
    > Get rid of the cast. All it does is inhibit warnings.
    >
    > >
    > > This piece of code gives "Got a valid pointer". How come when I
    > > specify a size of zero, memory is allocated and ptr becomes a
    > > valid pointer? I am not able to get the proper reason, can
    > > anyone enlighten me the reason behind this?

    >
    > See above on the care and feeding of blanks. Once more, the
    > pointer is valid because the standard says it must be.


    The standard also allows malloc to return NULL in that situation.

    --
    pete
     
    pete, Mar 8, 2005
    #8
  9. Quentarez <> writes:
    > On 8 Mar 2005 02:18:13 -0800, s.subbarayan wrote:
    >
    >> Dear all,
    >> In one of our projects in a document about C coding standard it is
    >> stated as
    >> "Always check a pointer is NULL before calling free. Always set a
    >> free'd pointer to NULL to try to protect it from being used again
    >> later and causing memory leaks."
    >>

    > <snip>
    >
    > The purpose of free() is to deallocate memory that was allocated by any of
    > the allocation functions. If you do this:
    >
    > char *p = malloc(n);
    > if (p != NULL)
    > {
    > p = NULL;
    > }
    > free(p);
    >
    > you have just leaked memory.

    [snip]

    I don't think that's what the OP (or the coding standard he's asking
    about) meant. I think it means "Always check *whether* a pointer is
    NULL before calling free" (i.e., don't call free(NULL)). It's a bad
    rule unless it's intended to accomodate pre-ANSI implementations, but
    it doesn't cause memory leaks.

    --
    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.
     
    Keith Thompson, Mar 10, 2005
    #9
    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. Jim Culver

    coding standards

    Jim Culver, Sep 9, 2003, in forum: ASP .Net
    Replies:
    4
    Views:
    2,258
  2. shbgupta

    coding standards

    shbgupta, Jun 27, 2003, in forum: ASP .Net
    Replies:
    2
    Views:
    559
    Chance Hopkins
    Jun 27, 2003
  3. =?Utf-8?B?UHJhdmVlbg==?=

    ASP.NET Coding Standards

    =?Utf-8?B?UHJhdmVlbg==?=, Aug 12, 2004, in forum: ASP .Net
    Replies:
    4
    Views:
    8,493
    Kevin Spencer
    Aug 12, 2004
  4. Adam Knight

    C# coding Standards!!!

    Adam Knight, Jan 11, 2006, in forum: ASP .Net
    Replies:
    3
    Views:
    851
    Karl Seguin [MVP]
    Jan 11, 2006
  5. Akshay Loke
    Replies:
    3
    Views:
    378
    Akshay Loke
    Jul 11, 2008
Loading...

Share This Page