C: Why do unassigned pointers point to unpredictable memory and NOT point to NULL?

后端 未结 11 1428
没有蜡笔的小新
没有蜡笔的小新 2020-12-05 04:25

A long time ago I used to program in C for school. I remember something that I really hated about C: unassigned pointers do not point to NULL.

I asked many people in

相关标签:
11条回答
  • 2020-12-05 04:48

    Actually, it depends on the storage of the pointer. Pointers with static storage are initizalized with null pointers. Pointers with automatic storage duration are not initialized. See ISO C 99 6.7.8.10:

    If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:

    • if it has pointer type, it is initialized to a null pointer;
    • if it has arithmetic type, it is initialized to (positive or unsigned) zero;
    • if it is an aggregate, every member is initialized (recursively) according to these rules;
    • if it is a union, the first named member is initialized (recursively) according to these rules.

    And yes, objects with automatic storage duration are not initialized for performance reasons. Just imagine initializing a 4K array on every call to a logging function (something I saw on a project I worked on, thankfully C let me avoid the initialization, resulting in a nice performance boost).

    0 讨论(0)
  • 2020-12-05 04:48

    So, to sum up what ninjalj explained, if you change your example program slightly you pointers will infact initialize to NULL:

    #include <stdio.h>
    
    // Change the "storage" of the pointer-variables from "stack" to "bss"  
    int * randomA;
    int * randomB;
    
    void main() 
    {
      int * nullA = NULL;
      int * nullB = NULL;
    
      printf("randomA: %p, randomB: %p, nullA: %p, nullB: %p\n\n", 
         randomA, randomB, nullA, nullB);
    }
    

    On my machine this prints

    randomA: 00000000, randomB: 00000000, nullA: 00000000, nullB: 00000000

    0 讨论(0)
  • 2020-12-05 04:48

    For it to point to NULL it would have to have NULL assigned to it ( even if it was done automatically and transparently ).

    So, to answer your question, the reason a pointer can't be both unassigned and NULL is because a pointer can not be both not assigned and assigned at the same time.

    0 讨论(0)
  • 2020-12-05 04:50

    It's for performance.

    C was first developed around the time of the PDP 11, for which 60k was a common maximum amount of memory, many will have had a lot less. Unnecessary assignments would be particularly expensive is this kind of environment

    These days there are many many embedded devices that use C for which 60k of memory would seem infinite, the PIC 12F675 has 1k of memory.

    0 讨论(0)
  • 2020-12-05 04:50

    I think it comes from the following: there's no reason why memories should contain (when powered up) specific values (0, NULL or whatever). So, if not previously specifically written, a memory location can contain whatever value, that from your point of view, is anyway random (but that very location could have been used before by some other software, and so contain a value that was meaningful for that application, e.g. a counter, but from "your" point of view, is just a random number). To initialize it to a specific value, you need at least one instruction more; but there are situation where you don't need this initialization a priori, e.g. v = malloc(x) will assign to v a valid address or NULL, no matter the initial content of v. So, initializing it could be considered a waste of time, and a language (like C) can choose not to do it a priori. Of course, nowadays this is mainly insignificant, and there are languages where uninitialized variables have default values (null for pointers, when supported; 0/0.0 for numerical... and so on; lazy initialization of course make it not so expensive to initialize an array of say 1 million elements, since they are initialized for real only if accessed before an assignment).

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