Thread: static v automatic storage, initialising pointers to nil

  1. #1
    Registered User
    Join Date
    Mar 2008
    Posts
    17

    static v automatic storage, initialising pointers to nil

    Hi,

    I am trying to understand how to manage arrays of pointers to structs. I built up some (verbose) simple code to build a struct containing an array of pointers to other structs. The main purpose is to really understand the increasingly complex syntax the more structs, pointers and arrays of pointers there are...

    On line 41 I declare Item_Array my_array. And on line 60 I am looping through my_array (if pitem is not NULL) testing if the value in that array index is equal to NULL.

    Why/How/When are the pointers in the my_array.items array initialised to NULL ? The declaration on line 41 means this struct is in automatic storage? Does that simply mean the reference (implying that my_array really contains a ptr under the hood) to the real struct? And that the real struct itself, because it is declared in static storage, initialises the pointers to NULL ?


    My code:
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define MAXTEXT 15
    #define MAXITEMS 10
    
    typedef struct {
        int i;
        char text[MAXTEXT];
    } Item; /* our new type is called Item */
    
    typedef struct {
        Item *items[MAXITEMS];
    } Item_Array;
    
    /* pointer to show uninitialised state in static storage */
    Item *myitem;
    
    int main(int argc, char **argv) {
    
        /* pointer to show uninitialised state in automatic storage */
        Item *myitem2;
    
        printf("uninitialised: myitem %p (static storage) is nil\n", myitem);
        printf("uninitialised: myitem2 %p (automatic storage) is garbage.\n", myitem2);
    
        /* create some items */
        Item item1, item2, item3;
    
        item1.i = 1;
        strncpy(item1.text, "one", MAXTEXT);
    
        item2.i = 2;
        strncpy(item2.text, "two", MAXTEXT);
    
        item3.i = 3;
        strncpy(item3.text, "three", MAXTEXT);
    
        /* create a struct with an array of pointers to our items */
        Item_Array my_array;
    
        /* array of pointers should contain the addresses of item structs &item_struct */
        my_array.items[0] = &item1;
        my_array.items[1] = &item2;
        my_array.items[2] = &item3;
    
        /* create an item on the heap */
        Item *fifth_item = malloc(sizeof(Item));
        (*fifth_item).i = 5; /* pointer to struct (*pitem), then struct member .i */
        strncpy((*fifth_item).text, "five on heap", MAXTEXT);
        my_array.items[4] = fifth_item; /* pointer is already the address of the item */
    
        int i;
        for (i = 0; i < MAXITEMS; i++) {
    
            Item *pitem; /* will hold a reference to the array item, to make things below more readable */
            pitem = my_array.items[i]; /* array index contains pointer (address) to item struct */
    
            if (pitem != NULL) {
                /* dereference pointer to struct (*pitem), then access member with struct notation of .i */
                printf("[%d] %d, %s, address %p\n", i, (*pitem).i, (*pitem).text, pitem);
            }
            else {
                printf("[%d] uninitialised, is %p\n", i, pitem);
            }
        }
    
        /* remember, remember, the fifth of November */
        free(fifth_item);
    
        return 0;
    }
    The output when run:
    Code:
    # ./pointers 
    uninitialised: myitem (nil) (static storage) is nil
    uninitialised: myitem2 0x7ffe930ac3e0 (automatic storage) is garbage.
    [0] 1, one, address 0x7ffe930ac2c0
    [1] 2, two, address 0x7ffe930ac2a0
    [2] 3, three, address 0x7ffe930ac280
    [3] uninitialised, is (nil)
    [4] 5, five on heap, address 0xb02010
    [5] uninitialised, is (nil)
    [6] uninitialised, is (nil)
    [7] uninitialised, is (nil)
    [8] uninitialised, is (nil)
    [9] uninitialised, is (nil)
    Last edited by dougieb; 09-09-2018 at 04:27 AM. Reason: added the output when running the code

  2. #2
    Registered User
    Join Date
    Dec 2011
    Location
    Namib desert
    Posts
    94
    In C, global variables, like myItem are initialized to 0 or NULL by the compiler !
    Item_Array my_array is not a global variable and thus not initialized, only during run-time you assign values of a struct addresses.

  3. #3
    Registered User
    Join Date
    Mar 2008
    Posts
    17
    Quote Originally Posted by ddutch View Post
    In C, global variables, like myItem are initialized to 0 or NULL by the compiler !
    Item_Array my_array is not a global variable and thus not initialized, only during run-time you assign values of a struct addresses.
    Yes, I understand that. But my_array appears to be initialised to nil in every array index position, rather than random/garbage data. How did that happen?

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,667
    You can't say anything about the state of uninitialized local variables.

    Could be apparently random.
    Could be zeros.
    Could be an exception just for trying to find out.

    Quite often, the memory is zero filled and the first time you use it in a small program, it all looks nice and tidy.

    But after lots of function calls, malloc and free, lots of things really do contain junk.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Mar 2008
    Posts
    17
    so immediately after line 41 (and for any non-static variables), the correct thing to do is loop through the array setting each index value to nil ?

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,667
    Yes.

    Or initialise it with
    Code:
    Item_Array my_array = { { 0 } };
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Mar 2008
    Posts
    17
    cool, thanks. I think I was mis-understanding the 'luckiness' of having the array pointer values always showing up as nil, when it's just as you say that early in a small program it's just by chance.

    thanks

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Static storage class
    By vead in forum C Programming
    Replies: 10
    Last Post: 02-21-2018, 10:31 AM
  2. Difference between Automatic and Static variable
    By viciousv322 in forum C++ Programming
    Replies: 6
    Last Post: 12-18-2005, 04:03 AM
  3. Static vs. Automatic Variables
    By Trekkie in forum C++ Programming
    Replies: 5
    Last Post: 11-14-2005, 02:55 PM
  4. Initialising pointers
    By patch1024 in forum C Programming
    Replies: 14
    Last Post: 05-27-2005, 02:23 PM
  5. Automatic vs. Static Duration
    By JMB in forum C++ Programming
    Replies: 7
    Last Post: 10-14-2002, 07:16 PM

Tags for this Thread