The Ever-Expanding Pointer Array

Perhaps the most difficult part of learning C is understanding and coding pointers. Even when you have a grip on things, it helps to keep fresh and practice new and utterly obnoxious ways to play with pointers.

First, I’m creating a new rule rising from a post I made on LinkedIn. The feedback I’ve received from fellow C programmers is to always initialize your pointers variables to NULL. In fact, one coder said to initialize all of your variables, no matter what the data type.

I like this idea. In fact, in many programming languages, all variables are initialized to zero or some default value like NULL; strings are declared as empty.

Second, I was trying to figure out a way to incrementally expand an array of pointers. Not just a construction like an array of strings, but a pointer that holds the addresses of allocated buffers. This goal proved to be an interesting mind game that I believe I can attempt only while sober.

To start, here is sample code, the base upon which I built my monster:

2025_10_11-Lesson.c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/* allocate storage for ten integers */
int *ten(void)
{
    int *iptr = NULL;

    iptr = malloc( sizeof(int) * 10 );

    return(iptr);
}

int main()
{
    int *tenint = NULL;
    int x;

    /* seed the randomizer */
    srand( (unsigned)time(NULL) );

    /* get the storage */
    tenint = ten();
    if( tenint==NULL )
    {
        fprintf(stderr,"Unable to allocate\n");
        exit(1);
    }
    puts("Storage for 10 integers allocated");

    /* assign the values */
    for( x=0; x<10; x++ )
        *(tenint+x) = rand() % 10 + 10;

    /* output the results */
    for( x=0; x<10; x++ )
        printf("%d\n",*(tenint+x) );

    /* clean-up */
    free(tenint);
    return 0;
}

The ten() function allocates storage for ten integers. Variable iptr is initialized to NULL, which is my new thing. The function does no error-checking, returning either a valid address for allocated storage or NULL for some kind of booboo.

In the main() function, int pointer tenint holds an address for integer storage. It’s initialized to NULL: int *tenint = NULL;

The randomizer is seeded: srand( (unsigned)time(NULL) );

The ten() function is called with the value returned stored in variable tenint. A check is made to confirm proper allocation; upon failure, the program exits.

Upon success, a for loop allocates random values from 10 through 19 to the ten integer-sized cubbies in memory, stored in pointer tenint:

for( x=0; x<10; x++ )
    *(tenint+x) = rand() % 10 + 10;

The expression *(tenint+x) references each subsequent integer-sized cubby stored at address tenint. The result of tenint+x is calculated by using pointer math: each value of x increases the offset by an integer-sized chunk in memory. The * (dereferencing) operator refers to the value at the location, which is where the random integer is stored.

The next for loop outputs the stored values. Then storage is freed and the program ends.

Here’s a sample run:

Storage for 10 integers allocated
11
16
15
14
15
16
10
15
17
12

Each run generates a different set of integers. Nothing guarantees that values aren’t repeated or in any specific order.

This code represents only the base. My goal is to add another stick of ten integers, and then another one after that. The program keeps adding batches of ten integers and manages them all. This process begins starting with next week’s Lesson.

Leave a Reply