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.

Answer from David C. Rankin on Stack Overflow
🌐
GeeksforGeeks
geeksforgeeks.org β€Ί c language β€Ί array-of-pointers-in-c
Array of Pointers in C - GeeksforGeeks
July 23, 2025 - In C, a pointer array is a homogeneous collection of indexed pointer variables that are references to a memory location. It is generally used in C Programming when we want to point at multiple memory locations of a similar data type in our C program.
Top answer
1 of 3
9

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.

2 of 3
3

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

Discussions

An array of pointers vs a pointer to an array
Declarations in C are written to match their usage. So if you write int *array[100], this means array has type such that *array[100] is of type int. (Ignoring, of course, that 100 is an invalid array index!) So to determine the type of array, we can use the operator precedence rules. Array indexing is higher precedence than dereferencing, so *array[100] means that we first get index into an array, and then dereference the object we get out, and that all should result in an int. This means that array is an array of pointers to int. (*array)[100] reverses this. Now, it says if we dereference array, and then index into whatever we get out as an array, we get an int. Thus, it's a pointer to an array of ints. Lots of people try to explain this in terms of the 'right-left rule' or the 'spiral rule' or whatever - I find these just make things harder. It's all operator precedence. More on reddit.com
🌐 r/C_Programming
6
5
February 1, 2021
I am trying to implement a link list in C using array of pointers which does not sit well with me because it feels like it not the most efficient way use of memory , i would just like get some suggestions on how can i improve on this given code.
You shouldn't implement a linked list with an array of pointers; you could instead just use the array. Instead, just set the next pointer of each node to point to the next element directly. (Alternately, don't use a linked list at all, and use a heap-allocated array that you resize with realloc.) More on reddit.com
🌐 r/cprogramming
14
0
April 2, 2025
What are Array of Pointers?
If you have something like const char *argv[] = {"./a.out", "hello", NULL}; You get this in memory: argv β”Œβ”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ ptr β”œβ”€β”€β”€β–Ίβ”‚ ./a.out β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ ptr β”œβ”€β” β”œβ”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ NULL β”‚ └─►│ hello β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ You can see that the "./a.out" and "hello" are stored in other places in memory, not inside the array. That’s what a pointer isβ€”a value that can point to another location in memory. Or it can be NULL, which does not point to anything. More on reddit.com
🌐 r/C_Programming
32
37
December 17, 2024
Is there any reasons for using C arrays instead of std::array ?
No. std::array exists exactly to solve this issue inherited from C. It can do everything that a C-style array does and more. More on reddit.com
🌐 r/cpp_questions
131
37
January 14, 2024
🌐
Reddit
reddit.com β€Ί r/c_programming β€Ί what are array of pointers?
r/C_Programming on Reddit: What are Array of Pointers?
December 17, 2024 -

So i am learning command lines arguments and just came cross char *argv[]. What does this actually do, I understand that this makes every element in the array a pointer to char, but i can't get around as to how all of this is happening. How does it treat every other element as another string? How come because essentialy as of my understanding rn, a simple char would treat as a single contiguous block of memory, how come turning this pointer to another pointer of char point to individual elements of string?

Top answer
1 of 14
79
If you have something like const char *argv[] = {"./a.out", "hello", NULL}; You get this in memory: argv β”Œβ”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ ptr β”œβ”€β”€β”€β–Ίβ”‚ ./a.out β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ ptr β”œβ”€β” β”œβ”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ NULL β”‚ └─►│ hello β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ You can see that the "./a.out" and "hello" are stored in other places in memory, not inside the array. That’s what a pointer isβ€”a value that can point to another location in memory. Or it can be NULL, which does not point to anything.
2 of 14
13
The only thing that’s guaranteeing is contiguous are the double pointers. If you dereference the first element, that is a pointer to a char, and there might be more chars further along if you move down that row with pointer arithmetic. Dereferencing your second element would be a pointer to another char which might make up a string along that row too (if you defined it as such). Those derefenced pointers have no reason to be contiguous in memory. It’s just that the pointers for themselves are. The only contiguity guarantee here from that statement alone is the array of pointers to char *.
🌐
Cornell Computer Science
cs.cornell.edu β€Ί courses β€Ί cs3410 β€Ί 2024fa β€Ί notes β€Ί pointer.html
Arrays & Pointers - CS 3410
You can think of the array having a base address \(b\). Then, the address of an element at index \(i\) has this address: ... In fact, C lets you treat an array itself as if it were a pointer to the first element: i.e., the base address \(b\).
🌐
TutorialsPoint
tutorialspoint.com β€Ί cprogramming β€Ί c_array_of_pointers.htm
Array of Pointers in C
Just like an integer array holds a collection of integer variables, an array of pointers would hold variables of pointer type. It means each variable in an array of pointers is a pointer that points to another address.
🌐
W3Schools
w3schools.com β€Ί c β€Ί c_pointers_arrays.php
C Pointers and Arrays
Well, in C, the name of an array, is actually a pointer to the first element of the array.
Find elsewhere
🌐
Medium
medium.com β€Ί @Dev_Frank β€Ί pointer-to-an-array-26e481f8deb0
POINTER TO AN ARRAY. Array of pointers | by Dev Frank | Medium
February 23, 2024 - It then uses ptrToArray to access and print each element of the array in a loop. The key point is that these two pointers have different purposes and should be used accordingly based on the intended operation. n C, you can use the sizeof operator to illustrate the sizes of pointers to arrays.
🌐
Microchip Developer Help
developerhelp.microchip.com β€Ί xwiki β€Ί bin β€Ί view β€Ί software-tools β€Ί compilers β€Ί c-programming β€Ί data-pointers β€Ί arrays-of-pointers
C Programming Arrays Of Pointers - Developer Help
August 26, 2025 - ... Are you sure you want to leave ... the changes auto-saved by the realtime editing session. ... An array of pointers is an ordinary array variable whose elements happen to be all pointers....
🌐
Carleton University
people.scs.carleton.ca β€Ί ~mjhinek β€Ί W13 β€Ί COMP2401 β€Ί notes β€Ί Arrays_and_Pointers.pdf pdf
T h e G r o u p o f T h r e e 2013 Arrays and Pointers Class Notes
In C , name of the array always points to the first element of an array. Here, address of first element of Β· an array is &age[0]. Also, age represents the address of the pointer where it is pointing.
🌐
GeeksforGeeks
geeksforgeeks.org β€Ί c language β€Ί how-to-declare-and-initialize-an-array-of-pointers-to-a-structure-in-c
How to Declare and Initialize an Array of Pointers to a Structure in C? - GeeksforGeeks
July 23, 2025 - You can clearly see in the above code how we have initialized the structure pointer array at the end. The difference between this and static arrays is just that static arrays are allocated in stack memory, while these are allocated in heap memory. And so, you can resize these arrays anytime you want. We can access these arrays just like we did with the static ones so there is no change in syntax for that. Note: In case of static arrays, you can initialize the array all at once during the time of initialization like - node *struct_arr [10 ] = { struct_ptr1, struct_ptr2, struct_ptr3 .....
🌐
CS Fundamentals
cs-fundamentals.com β€Ί c-programming β€Ί arrays-in-c
One, Two-Dimensional (2D) Arrays and Pointers in C
Arrays become useful storage containers when the size of the list is know beforehand. Array name in C language behaves like a constant pointer and represents the base address of the array.
🌐
TutorialsPoint
tutorialspoint.com β€Ί cprogramming β€Ί c_pointer_to_an_array.htm
Pointer to an Array in C
In this code, we have a pointer ptr that points to the address of the first element of an integer array called balance.
🌐
Log2Base2
log2base2.com β€Ί C β€Ί pointer β€Ί 2d-array-and-pointers-in-c.html
2d array and pointers in c
Since *arr holds the address of the first element, **arr will give the value stored in the first element. If we move **arr by 1 position(**arr+1), the value will be incremented by 1. If the array first element is 10, **arr+1 will be 11. 1. &arr is a 2D array pointer (int*)[row][col]. So, &arr+1 will point the next 2D block.
🌐
Medium
medium.com β€Ί @Dev_Frank β€Ί pointer-arrays-08100ef37ede
POINTER & ARRAYS. Understanding C Pointers and Arrays | by Dev Frank | Medium
February 17, 2024 - Notice that the last digits in each element’s memory address differ, incrementing by 4, reflecting the typical size of an integer (4 bytes). In C, the array’s name is essentially a pointer to its first element.
🌐
DEV Community
dev.to β€Ί bitecode β€Ί array-and-pointer-in-c-14mp
Array and Pointer in C - DEV Community
April 10, 2020 - Is array a pointer in C? seems we can treat it as a pointer when we access its element. But sometimes Array has different behavior from pointer. ... If arr here is a pointer, then seems this should print out the size of a pointer (4 or 8, depends ...
🌐
Dyclassroom
dyclassroom.com β€Ί c β€Ί c-pointers-and-one-dimensional-array
C - Pointers and One Dimensional Array - C Programming - dyclassroom | Have fun learning :-)
So, ptr points at the array str. When we increment the pointer variable it points to the next memory location based on the size of the data type. So, ptr character pointer variable is pointing at the first memory location of the one dimensional character array str.
🌐
Unstop
unstop.com β€Ί home β€Ί blog β€Ί array of pointers in c explained with detailed code examples
Array Of Pointers In C Explained With Detailed Code Examples
February 29, 2024 - An array of pointers in C is a data structure containing pointers to variables of the same data types that are stored in continuous memory locations.
🌐
Upgrad
upgrad.com β€Ί home β€Ί tutorials β€Ί software & tech β€Ί array of pointers in c
Array of Pointers in C | Beginner’s Guide
April 30, 2025 - Before diving deeper, it's important ... and challenges. An array of pointers in C is a collection of pointers, each pointing to a different variable or memory location....