Creating a Pointer Array (Correct)

Unlike the iffy issue with assigning a pointer directly to a string, you cannot declare a pointer and assign it an immediate value. This puzzle was presented in last week’s Lesson. No, to do things properly requires not a single statement but three separate steps.

These steps are:

1. Declare the pointer
2. Allocate storage
3. Assign values

Declaring the pointer is done like any other variable, though at this point in the code it’s uninitialized:

int *nums;

The pointer could be initialized at declaration, providing the above statement (or similar) is set in the code after another variable or memory location is established. Still, being a traditionalist, I place my variable declarations at the start of the code, well before any action.

The second step is to allocate storage. For this job, I use the malloc() function to create a chunk of memory adequate to store the data. From last week’s example, the data consists of three int values:

nums = (int *)malloc( sizeof(int) * 3 );
if( nums==NULL )
{
    fprintf(stderr,"Memory allocation error\n");
    exit(1);
}

The malloc() function is typecast to an int pointer. Its allocation consists of a memory chunk equal to the size of an integer multiplied by three: sizeof(int) * 3. The address is assigned to the nums pointer, which is immediately tested against the NULL defined constant. A positive test means the allocation failed, and the code responds appropriately.

After creating the pointer and assigning it an appropriately-sized chunk of memory, values are assigned:

for( x=0; x<3; x++ )
    *(nums+x) = x+1;

The for loop steps thrice, each time assigning an offset within the memory buffer (referenced by nums) to the value x+1.

Here is the full code:

2021_05_22-Lesson.c

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

int main()
{
    int *nums;
    int x;

    /* allocate storage for 3 integers */
    nums = (int *)malloc( sizeof(int) * 3 );
    if( nums==NULL )
    {
        fprintf(stderr,"Memory allocation error\n");
        exit(1);
    }

    /* assign the integer values */
    for( x=0; x<3; x++ )
        *(nums+x) = x+1;

    /* output the results */
    printf("%d %d %d\n",
            *(nums+0),
            *(nums+1),
            *(nums+2)
          );

    return(0);
}

Granted, it would be easier if this expression worked:

int *nums = { 1, 2, 3 };

The problem is that the { 1, 2, 3 } thing is a “scalar,” not an array; declaring it in the statement doesn’t allocate storage and set those values into memory. They must already exist in memory for declaration/assignment to work. Or, as demonstrated in this post, the pointer must be declared, storage allocated, and then storage filled to properly perform the task.

“But what about assigning a pointer to a string?”

My guess is that the pointer string assignment works because the compiler allocates storage for strings declared in your source code:

char *prompt = "Type something: ";

This declaration works because the compiler knows the string’s address when it’s set into memory. The pointer absorbs the memory location. But the problem with assigning a string thin this manner is that the location doesn’t behave the same as if the storage was allocated as demonstrated in this Lesson.

So while this declaration is kosher:

int nums[] = { 1, 2, 3 };

This one is not:

int *nums = { 1, 2, 3 };

The compiler has no obligation to create the “scalar” and assign it an address. It seems like it would, but no.

Regardless of my guesses, my point is that you cannot allocate a pointer to an array of values unless it’s a string. Even then, be wary when creating a pointer to a string as its behavior is inconsistent with more traditional and properly-created strings.

Leave a Reply