How Do You Create an Array of Pointers in C?

How Do You Create an Array of Pointers in C?

How do I create an array of pointers where each element holds a pointer to some other value

For example if I have

int** arr[5] = {0xbfjeabfbfe,0x...}; //is it the right way to do it?

And what it means to have an array type of void? like void **newArray[5];

And let's say I want to dynamically allocate memory for an array of pointers using malloc or calloc!! What will be the syntax be?

3 Answers

How do you create an array of pointers in C?

To create an array of pointers in C, you have one option, you declare:

  type *array[CONST];  /* create CONST number of pointers to type */

With C99+ you can create a Variable Length Array (VLA) of pointers, e.g.

  type *array[var];   /* create var number of pointers to type */

The standard defines both in C11 Standard - 6.7.6.2 Array declarators and discusses subscripting in C11 Standard - 6.5.2.1 Array subscripting.

A short example using an array of pointers, assigning a pointer to each row in a 2D array to an array of pointers to int, e.g.

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

#define COL 3
#define MAX 5

int main (void) {

    int arr2d[MAX][COL] = {{ 0 }},  /* simple 2D array */
        *arr[MAX] = { NULL },       /* 5 pointers to int */
        i, j, v = 0;

    for (i = 0; i < MAX; i++) {     /* fill 2D array */
        for (j = 0; j < COL; j++)
            arr2d[i][j] = v++;
        arr[i] = arr2d[i];          /* assing row-pointer to arr */
    }

    for (i = 0; i < MAX; i++) {     /* for each pointer */
        for (j = 0; j < COL; j++)   /* output COL ints */
            printf (" %4d", arr[i][j]);
        putchar ('\n');
    }
}

Example Use/Output

$ ./bin/array_ptr2int_vla
    0    1    2
    3    4    5
    6    7    8
    9   10   11
   12   13   14

Another fundamental of C is the pointer-to-pointer, but it is not an "Array", though it is routinely called a "dynamic array" and can be allocated and indexed simulating an array. The distinction between an "Array" and a collection of pointers is that with an Array, all values are guaranteed to be sequential in memory -- there is no such guarantee with a collection of pointers and the memory locations they reference.

So What Does int **arr[CONST] Declare?

In your question you posit a declaration of int** arr[5] = {0xbfjeabfbfe,0x...};, so what does that declare? You are declaring Five of something, but what? You are declaring five pointer-to-pointer-to-int. Can you do that? Sure.

So what do you do with a pointer-to-pointer-to-something? The pointer-to-poitner forms the backbone of dynamically allocated and reallocated collection of types. They are commonly termed "dynamically allocated arrays", but that is somewhat a misnomer, because there is no guarantee that all values will be sequential in memory. You will declare a given number of pointers to each int** in the array. You do not have to allocate an equal number of pointers.

(note: there is no guarantee that the memory pointed to by the pointers will even be sequential, though the pointers themselves will be -- make sure you understand this distinction and what an "Array" guarantees and what pointers don't)

int** arr[5] declares five int**. You are then free to assign any address to you like to each of the five pointers, as long as the type is int**. For example, you will allocate for your pointers with something similar to:

  arr[i] = calloc (ROW, sizeof *arr[i]);  /* allocates ROW number of pointers */

Then you are free to allocate any number of int and assign that address to each pointer, e.g.

  arr[i][j] = calloc (COL, sizeof *arr[i][j]); /* allocates COL ints */

You can then loop over the integers assigning values:

  arr[i][j][k] = v++;

A short example using your int** arr[5] type allocation could be similar to:

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

#define ROW 3
#define COL ROW
#define MAX 5

int main (void) {

    int **arr[MAX] = { NULL },  /* 5 pointer-to-pointer-to-int */
        i, j, k, v = 0;

    for (i = 0; i < MAX; i++) { /* allocate ROW pointers to each */
        if ((arr[i] = calloc (ROW, sizeof *arr[i])) == NULL) {
            perror ("calloc - pointers");
            return 1;
        }
        for (j = 0; j < ROW; j++) { /* allocate COL ints each pointer */
            if ((arr[i][j] = calloc (COL, sizeof *arr[i][j])) == NULL) {
                perror ("calloc - integers");
                return 1;
            }
            for (k = 0; k < COL; k++)   /* assign values to ints */
                arr[i][j][k] = v++;
        }
    }

    for (i = 0; i < MAX; i++) { /* output each pointer-to-pointer to int */
        printf ("pointer-to-pointer-to-int: %d\n\n", i);
        for (j = 0; j < ROW; j++) {     /* for each allocated pointer */
            for (k = 0; k < COL; k++)   /* output COL ints */
                printf ("  %4d", arr[i][j][k]);
            free (arr[i][j]);   /* free the ints */
            putchar ('\n');
        }
        free (arr[i]);      /* free the pointer */
        putchar ('\n');
    }

    return 0;
}

You have allocated for five simulated 2D arrays assigning the pointer to each to your array of int **arr[5], the output would be:

Example Use/Output

$ ./bin/array_ptr2ptr2int
pointer-to-pointer-to-int: 0

     0     1     2
     3     4     5
     6     7     8

pointer-to-pointer-to-int: 1

     9    10    11
    12    13    14
    15    16    17

pointer-to-pointer-to-int: 2

    18    19    20
    21    22    23
    24    25    26

pointer-to-pointer-to-int: 3

    27    28    29
    30    31    32
    33    34    35

pointer-to-pointer-to-int: 4

    36    37    38
    39    40    41
    42    43    44

Hopefully this has helped with the distinction between an array of pointers, and an array of pointers-to-pointer and shown how to declare and use each. If you have any further questions, don't hesitate to ask.

An array of pointers to ints;

int x = 1;
int y = 42;
int z = 12;

int * array[3];

array[0] = &x;
array[1] = &y;
array[2] = &z;

alternate syntax

int * array[] = {&x,&y,&z};

keeping it simple. Work upwards from there

4

How do I create an array of pointers where each element holds a pointer to some other value

An array of arrays can be though of as a 3D matrix

int*** arr;    // Points to an array of arrays (3 Dimensions)
int** arr[0];  // Points to an array           (2 Dimensions)
int* arr[0][0];// Points to a single element   (1 Dimension)

If you know the size before hand you can initialize a 3D array like this:

int arr[2][2][2] = {
   { {1, 2}, {3, 4} },
   { {5, 6}, {7, 8} },
}

But its not very readable for non trivial n-dimensional arrays. Another approach is to loop over each dimension.

int*** arr;
int dimensions = 10;

arr = malloc(dimensions * sizeof(int**)); // Allocate an array of 2D arrays

for (int i = 0; i < dimensions; i++) {
  arr[i] = malloc(dimensions * sizeof(int*)); // Allocate an array of arrays 

  for (int j = 0; j < dimensions; j++) {
      arr[i][j] = malloc(dimensions * sizeof(int)); // Allocate array

      for (int k = 0; k < dimensions; k++) {
          arr[i][j][k] = 0; // Fill each element with 0's
      }
  }
}

This approach also lets to dynamically allocate the arrays.

And what it means to have an array type of void? like void **newArray[5];

void* is a pointer to an unknown type. If int* means a pointer to an int, void* means a pointer to a value who's type is unknown.

2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

James H. Sterling
Author

James H. Sterling

James Sterling reports on renewable energy developments, climate policy, ecological conservation, and green tech innovations around the globe.