checking for NULL before calling free

前端 未结 8 622
终归单人心
终归单人心 2020-12-03 13:45

Many C code freeing pointers calls:

if (p)
  free(p);

But why? I thought C standard say the free function doesn\'t do anything

相关标签:
8条回答
  • 2020-12-03 13:55

    The construct:

    free(NULL);
    

    has always been OK in C, back to the original UNIX compiler written by Dennis Ritchie. Pre-standardisation, some poor compilers might not have fielded it correctly, but these days any compiler that does not cannot legitimately call itself a compiler for the C language. Using it typically leads to clearer, more maintainable code.

    0 讨论(0)
  • 2020-12-03 13:56

    There are two distinct reasons why a pointer variable could be NULL:

    1. because the variable is used for what in type theory is called an option type, and holds either a pointer to an object, or NULL to represent nothing,

    2. because it points to an array, and may therefore be NULL if the array has zero length (as malloc(0) is allowed to return NULL, implementation-defined).

    Although this is only a logical distinction (in C there are neither option types nor special pointers to arrays and we just use pointers for everything), it should always be made clear how a variable is used.

    That the C standard requires free(NULL) to do nothing is the necessary counterpart to the fact that a successful call to malloc(0) may return NULL. It is not meant as a general convenience, which is why for example fclose() does require a non-NULL argument. Abusing the permission to call free(NULL) by passing a NULL that does not represent a zero-length array feels hackish and wrong.

    0 讨论(0)
  • 2020-12-03 14:03

    Compilers, even when inlining are not smart enough to know the function will return immediately. Pushing parameters etc on stack and setting the call up up is obviously more expensive than testing a pointer. I think it is always good practice to avoid execution of anything, even when that anything is a no-op. Testing for null is a good practice. An even better practice is to ensure your code does not reach this state and therefore eliminate the need for the test altogether.

    0 讨论(0)
  • 2020-12-03 14:06

    If you rely on that free(0) is OKAY, and it's normal for your pointer to be null at this point, please say so in comment // may be NULL

    This may be merely self-explanatory code, saying yes I know, I also use p as a flag.

    0 讨论(0)
  • 2020-12-03 14:12

    I tend to write "if (p) free(p)" a lot, even if I know it's not needed.

    I partially blame myself because I learned C the old days when free(NULL) would segfault and I still feel uncomfortable not doing it.

    But I also blame the C standard for not being consistent. Would, for example, fclose(NULL) be well defined, I would not have problems in writing:

    free(p);
    fclose(f);
    

    Which is something that happens very often when cleaning up things. Unfortunately, it seems strange to me to write

    free(p);
    if (f) fclose(f);
    

    and I end up with

    if (p) free(p);
    if (f) fclose(f);
    

    I know, it's not a rational reason but that's my case :)

    0 讨论(0)
  • 2020-12-03 14:17
    if (p)
        free(p);
    

    why another explicit check?

    If I write something like that, it's to convey the specific knowledge that the pointer may be NULL...to assist in readability and code comprehension. Because it looks a bit weird to make that an assert:

    assert(p || !p);
    free(p);
    

    (Beyond looking strange, compilers are known to complain about "condition always true" if you turn your warnings up in many such cases.)

    So I see it as good practice, if it's not clear from the context.

    The converse case, of a pointer being expected to be non null, is usually evident from the previous lines of code:

    ...
    Unhinge_Widgets(p->widgets);
    free(p); // why `assert(p)`...you just dereferenced it!
    ...
    

    But if it's non-obvious, having the assert may be worth the characters typed.

    0 讨论(0)
提交回复
热议问题