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

C: pointer to array of pointers to structures (allocation/deallocation issues) - Stack Overflow
Is this correct? My issue is working with this thing. So each pointer in the array points to something that is allocated separately. But I think I need to do this first: ... I am having trouble understanding the above. Do I need to do this, and why do I need to do this? In particular, what does it mean to allocate memory for pointers if I am going to be allocating memory for each thing that the pointer points to? Say now I have pointer to an array of ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Are C arrays pointers ?
Is it because arrays are not pointers and increment operator is not defined for arrays ? That is correct. Technically speaking, even in myArray++ the array is converted to a pointer. However, that pointer does not have a location in memory โ€” it is not an "lvalue". The increment operator can only be used on mutable lvalues. It's pretty much the same reason 42++ makes no sense. 42 doesn't have a location in memory either. More on reddit.com
๐ŸŒ r/C_Programming
29
42
June 5, 2024
What is the purpose of arrays in C, when pointers could have done the job? - Software Engineering Stack Exchange
Arrays and pointers are not the same thing in C, although they are related and can be used similarly. So far we all agree. However, I don't see why arrays were included in C, when pointers could h... More on softwareengineering.stackexchange.com
๐ŸŒ softwareengineering.stackexchange.com
October 20, 2011
changing base address of array with pointers?

why afterall both 'b' and 'a' point to memory address of array

Because you don't change either of them? Note that you can't add to a. a is an array, you can't add to arrays. b however is a pointer. You can add to pointers to change where they point. Under most circumstances, an object of array type is implicitly converted to a pointer to the first element of that array, but the result is not an lvalue, so you can't assign to it. I hope this explains your confusion.

More on reddit.com
๐ŸŒ r/C_Programming
9
6
December 9, 2015
People also ask

How do I declare an array of pointers?

To declare an array of pointers, you'd specify the pointer type first, followed by the array name and its size. In C or C++, you might do something like int *arr[5];, which declares an array of 5 pointers to integers.

๐ŸŒ
lenovo.com
lenovo.com โ€บ home
Array of Pointers Explained: The Ultimate Guide | Lenovo US
What are the common use-cases for arrays of pointers?

Arrays of pointers are particularly useful when you're working with strings, dynamic memory allocation, or when you want to create an array of different-sized arrays. They're also handy for function pointers, allowing you to call different functions through your array elements.

๐ŸŒ
lenovo.com
lenovo.com โ€บ home
Array of Pointers Explained: The Ultimate Guide | Lenovo US
Can I initialize an array of pointers at the time of declaration?

Yes, you can initialize an array of pointers at the time of declaration. For example, you could write int *arr[] = {&x, &y, &z}; where x, y, z are integers already declared in your code. This will store the addresses of x, y, z in the array.

๐ŸŒ
lenovo.com
lenovo.com โ€บ home
Array of Pointers Explained: The Ultimate Guide | Lenovo US
๐ŸŒ
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 16
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 16
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 *.
๐ŸŒ
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.
๐ŸŒ
Quora
quora.com โ€บ How-can-I-make-an-array-of-pointers-to-structs-in-c
How to make an array of pointers to structs in c - Quora
Answer (1 of 9): [code]typedef struct { //stuff that goes in struct here } foo; int main() { foo localArray[100]; //example of stack-allocated //struct array foo* dynArray = (foo*)malloc(100*sizeof(foo)); //example of //heap allocated //struct array fo...
Find elsewhere
๐ŸŒ
Cprogramming
cboard.cprogramming.com โ€บ c-programming โ€บ 177497-array-pointers-pointers-pointers.html
Array of pointers, pointers to pointers.
May 2, 2019 - When you declare: ... char *p; You are telling the compiler to allocate space for a variable p (not "*p"!) which will store a memory address. Later, you can use the indirection operator * to use this address stored in p to access a char stored in memory. This: ... int a[2] = { 1, 2 }; Declares ...
๐ŸŒ
GNU
gnu.org โ€บ software โ€บ c-intro-and-ref โ€บ manual โ€บ html_node โ€บ Pointers-and-Arrays.html
Pointers and Arrays (GNU C Language Manual)
The name of the array, when used by itself as an expression (other than in sizeof), stands for a pointer to the arrayโ€™s zeroth element. Thus, array + 3 converts array implicitly to &array[0], and the result is a pointer to element 3, equivalent to &array[3].
๐ŸŒ
Lenovo
lenovo.com โ€บ home
Array of Pointers Explained: The Ultimate Guide | Lenovo US
This allows for the creation of ... commonly used in languages like C and C++. To declare an array of pointers, you'd specify the pointer type first, followed by the array name and its size....
๐ŸŒ
Scaler
scaler.com โ€บ topics โ€บ c โ€บ array-of-pointers-in-c
Array of Pointers in C - Scaler Topics
January 2, 2024 - Pointers can be associated with the multidimensional arrays (2-D and 3-D arrays) as well. Also, We can create an array of pointers to store multiple addresses of different variables. An array in C is a collection of variables, all of the same type, accessed using a common name.
๐ŸŒ
BYJUS
byjus.com โ€บ gate โ€บ array-of-pointers-in-c
An Array of Pointers in C
August 1, 2022 - Here are the three crucial things that come into play when dealing with pointers in C: ... When we want to point at multiple variables or memories of the same data type in a C program, we use an array of pointers.
Top answer
1 of 4
111

Allocated Array

With an allocated array it's straightforward enough to follow.

Declare your array of pointers. Each element in this array points to a struct Test:

struct Test *array[50];

Then allocate and assign the pointers to the structures however you want. Using a loop would be simple:

array[n] = malloc(sizeof(struct Test));

Then declare a pointer to this array:

                               // an explicit pointer to an array 
struct Test *(*p)[] = &array;  // of pointers to structs

This allows you to use (*p)[n]->data; to reference the nth member.

Don't worry if this stuff is confusing. It's probably the most difficult aspect of C.


Dynamic Linear Array

If you just want to allocate a block of structs (effectively an array of structs, not pointers to structs), and have a pointer to the block, you can do it more easily:

struct Test *p = malloc(100 * sizeof(struct Test));  // allocates 100 linear
                                                     // structs

You can then point to this pointer:

struct Test **pp = &p

You don't have an array of pointers to structs any more, but it simplifies the whole thing considerably.


Dynamic Array of Dynamically Allocated Structs

The most flexible, but not often needed. It's very similar to the first example, but requires an extra allocation. I've written a complete program to demonstrate this that should compile fine.

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

struct Test {
    int data;
};

int main(int argc, char **argv)
{
    srand(time(NULL));

    // allocate 100 pointers, effectively an array
    struct Test **t_array = malloc(100 * sizeof(struct Test *));

    // allocate 100 structs and have the array point to them
    for (int i = 0; i < 100; i++) {
        t_array[i] = malloc(sizeof(struct Test));
    }

    // lets fill each Test.data with a random number!
    for (int i = 0; i < 100; i++) {
        t_array[i]->data = rand() % 100;
    }

    // now define a pointer to the array
    struct Test ***p = &t_array;
    printf("p points to an array of pointers.\n"
       "The third element of the array points to a structure,\n"
       "and the data member of that structure is: %d\n", (*p)[2]->data);

    return 0;
}

Output:

> p points to an array of pointers.
> The third element of the array points to a structure,
> and the data member of that structure is: 49

Or the whole set:

for (int i = 0; i < 100; i++) {
    if (i % 10 == 0)
        printf("\n");
    printf("%3d ", (*p)[i]->data);
}

 35  66  40  24  32  27  39  64  65  26 
 32  30  72  84  85  95  14  25  11  40 
 30  16  47  21  80  57  25  34  47  19 
 56  82  38  96   6  22  76  97  87  93 
 75  19  24  47  55   9  43  69  86   6 
 61  17  23   8  38  55  65  16  90  12 
 87  46  46  25  42   4  48  70  53  35 
 64  29   6  40  76  13   1  71  82  88 
 78  44  57  53   4  47   8  70  63  98 
 34  51  44  33  28  39  37  76   9  91 

Dynamic Pointer Array of Single-Dynamic Allocated Structs

This last example is rather specific. It is a dynamic array of pointers as we've seen in previous examples, but unlike those, the elements are all allocated in a single allocation. This has its uses, most notable for sorting data in different configurations while leaving the original allocation undisturbed.

We start by allocating a single block of elements as we do in the most basic single-block allocation:

struct Test *arr = malloc(N*sizeof(*arr));

Now we allocate a separate block of pointers:

struct Test **ptrs = malloc(N*sizeof(*ptrs));

We then populate each slot in our pointer list with the address of one of our original array. Since pointer arithmetic allows us to move from element to element address, this is straight-forward:

for (int i=0;i<N;++i)
    ptrs[i] = arr+i;

At this point the following both refer to the same element field

arr[1].data = 1;
ptrs[1]->data = 1;

And after review the above, I hope it is clear why.

When we're done with the pointer array and the original block array they are freed as:

free(ptrs);
free(arr);

Note: we do NOT free each item in the ptrs[] array individually. That is not how they were allocated. They were allocated as a single block (pointed to by arr), and that is how they should be freed.

So why would someone want to do this? Several reasons.

First, it radically reduces the number of memory allocation calls. Rather then N+1 (one for the pointer array, N for individual structures) you now have only two: one for the array block, and one for the pointer array. Memory allocations are one of the most expensive operations a program can request, and where possible, it is desirable to minimize them (note: file IO is another, fyi).

Another reason: Multiple representations of the same base array of data. Suppose you wanted to sort the data both ascending and descending, and have both sorted representations available at the same time. You could duplicate the data array, but that would require a lot of copying and eat significant memory usage. Instead, just allocate an extra pointer array and fill it with addresses from the base array, then sort that pointer array. This has especially significant benefits when the data being sorted is large (perhaps kilobytes, or even larger, per item) The original items remain in their original locations in the base array, but now you have a very efficient mechanism in which you can sort them without having to actually move them. You sort the array of pointers to items; the items don't get moved at all.

I realize this is an awful lot to take in, but pointer usage is critical to understanding the many powerful things you can do with the C language, so hit the books and keep refreshing your memory. It will come back.

2 of 4
5

It may be better to declare an actual array, as others have suggested, but your question seems to be more about memory management so I'll discuss that.

struct Test **array1;

This is a pointer to the address of a struct Test. (Not a pointer to the struct itself; it's a pointer to a memory location that holds the address of the struct.) The declaration allocates memory for the pointer, but not for the items it points to. Since an array can be accessed via pointers, you can work with *array1 as a pointer to an array whose elements are of type struct Test. But there is not yet an actual array for it to point to.

array1 = malloc(MAX * sizeof(struct Test *));

This allocates memory to hold MAX pointers to items of type struct Test. Again, it does not allocate memory for the structs themselves; only for a list of pointers. But now you can treat array as a pointer to an allocated array of pointers.

In order to use array1, you need to create the actual structs. You can do this by simply declaring each struct with

struct Test testStruct0;  // Declare a struct.
struct Test testStruct1;
array1[0] = &testStruct0;  // Point to the struct.
array1[1] = &testStruct1;

You can also allocate the structs on the heap:

for (int i=0; i<MAX; ++i) {
  array1[i] = malloc(sizeof(struct Test));
}

Once you've allocated memory, you can create a new variable that points to the same list of structs:

struct Test **array2 = array1;

You don't need to allocate any additional memory, because array2 points to the same memory you've allocated to array1.


Sometimes you want to have a pointer to a list of pointers, but unless you're doing something fancy, you may be able to use

struct Test *array1 = malloc(MAX * sizeof(struct Test));  // Pointer to MAX structs

This declares the pointer array1, allocated enough memory for MAX structures, and points array1 to that memory. Now you can access the structs like this:

struct Test testStruct0 = array1[0];     // Copies the 0th struct.
struct Test testStruct0a= *array1;       // Copies the 0th struct, as above.
struct Test *ptrStruct0 = array1;        // Points to the 0th struct.

struct Test testStruct1 = array1[1];     // Copies the 1st struct.
struct Test testStruct1a= *(array1 + 1); // Copies the 1st struct, as above.
struct Test *ptrStruct1 = array1 + 1;    // Points to the 1st struct.
struct Test *ptrStruct1 = &array1[1];    // Points to the 1st struct, as above.

So what's the difference? A few things. Clearly, the first method requires you to allocate memory for the pointers, and then allocate additional space for the structs themselves; the second lets you get away with one malloc() call. What does the extra work buy you?

Since the first method gives you an actual array of pointers to Test structs, each pointer can point to any Test struct, anywhere in memory; they needn't be contiguous. Moreover, you can allocate and free the memory for each actual Test struct as necessary, and you can reassign the pointers. So, for example, you can swap two structures by simply exchanging their pointers:

struct Test *tmp = array1[2];  // Save the pointer to one struct.
array1[2] = array1[5];         // Aim the pointer at a different struct.
array1[5] = tmp;               // Aim the other pointer at the original struct.

On the other hand, the second method allocates a single contiguous block of memory for all of the Test structs and partitions it into MAX items. And each element in the array resides at a fixed position; the only way to swap two structures is to copy them.

Pointers are one of the most useful constructs in C, but they can also be among the most difficult to understand. If you plan to continue using C, it'll probably be a worthwhile investment to spend some time playing with pointers, arrays, and a debugger until you're comfortable with them.

Good luck!

๐ŸŒ
Reddit
reddit.com โ€บ r/c_programming โ€บ are c arrays pointers ?
r/C_Programming on Reddit: Are C arrays pointers ?
June 5, 2024 -

Hello,

I'm new to C and would like to understand the differences between pointers and arrays. Everyone keeps telling me arrays are pointers but the following situation confuses me :

When i declare an array :

int myArray[] = {1,2,3,4};

I can get a pointer on the first element of this array:

int* myPointer = myArray;

When iterating in a for loop, i can use the following :

*(myPointer+i) = ... or

*(myArray+i) = ...

When iterating in a while loop, i can use my pointer :

*myPointer++ = ... but can't use

*myArray++ = ...

Is it because arrays are not pointers and increment operator is not defined for arrays ?

Thanks for your help ๐Ÿ™‚

Top answer
1 of 14
45
Is it because arrays are not pointers and increment operator is not defined for arrays ? That is correct. Technically speaking, even in myArray++ the array is converted to a pointer. However, that pointer does not have a location in memory โ€” it is not an "lvalue". The increment operator can only be used on mutable lvalues. It's pretty much the same reason 42++ makes no sense. 42 doesn't have a location in memory either.
2 of 14
19
Arrays are not pointers. Arrays decay to pointers when used in an expression. In C, you can say something like: target: puts("Help, I'm stuck in a loop!\n"); goto target; The identifier target is a label. A code label. A place where you can transfer control flow using goto. In C, an array is like a data label. That is, an array is a name for a region of memory. If you use the array in an expression, it resolves to the address of the first byte of the region. That's the "decay" part. But it isn't a pointer, and it isn't an address (pointer value). It's a name for the region. There is more about memory layout for arrays at Row-major Order . Increment operator The reason why *(myArray + i) works is that myArray is an address value. It is not an lvalue, it is an rvalue. It is a "right-hand-side value", in that it goes on the right-hand-side of the equal sign in an assignment: some_pointer = myArray; Remember that myArray is the name given to a region of memory. If you could somehow change the meaning of myArray, you would move the region of memory. That is not something that standard C supports. (Although, see the m* functions in on Linux...) On the other hand, if you declare a true pointer, like int *myPointer = myArray; You have created another region of memory -- the storage for myPointer -- that is treated as a single object (an lvalue). So you can overwrite the value, assign to it, increment or decrement it, etc. myPointer++; // myPointer == &myArray[1] Remember that this is a variable that holds an address. That is, it is typed to store the kind of value that myArray represents -- the address of the first element in a region of memory storing a list of elements. Why does this happen? Ultimately, this is all about speed. It seems obvious that if you say int i = 2; float pi = 3.14; short ary[2] = { 1, 6 }; Then whenever you write the expression i you are intending to expand that to be the value 2 (or whatever is in that memory location after you keep evaluating all these expressions!). Likewise, if you write the term pi you intend it to expand to 3.14. In theory, if you write the expression ary (with no brackets afterwards) it should expand to the two values {1, 6}. Except that C doesn't support array values like that. (C has added struct assignment, but it was not in the original standards. C has never supported array assignment in a standard.) In some other language, that might work. Perl and Python, for example, have a notion of lists, and have syntactic sugar for converting args to lists, and lists to args, and have sugar for extracting slices from lists, so they can express a lot more stuff, at the price of passing "heavier" parameters (a pointer is really cheap to pass). Instead, C chose to have arrays "decay" to the address of their first element. This would enable writing a simple interface for functions, that just takes an address (aka "pointer") argument plus maybe a size.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ c language โ€บ how-to-initialize-array-of-pointers-in-c
How to Initialize Array of Pointers in C? - GeeksforGeeks
July 23, 2025 - We can simply initialize an array of pointers by assigning them some valid address using the assignment operator. Generally, we initialize the pointers that currently do not point to any location to a NULL value.
๐ŸŒ
Medium
medium.com โ€บ @Dev_Frank โ€บ pointer-arrays-08100ef37ede
POINTER & ARRAYS. Understanding C Pointers and Arrays | by Dev Frank | Medium
February 17, 2024 - &pointer gives the address of the pointer variable itself. 3. String Literal Initialization: char array[ ] = โ€œabcโ€` initializes the array with โ€˜aโ€™, โ€˜bโ€™, โ€˜cโ€™, and โ€˜\0โ€™. char *pointer = โ€œabcโ€` sets the pointer to the address of the โ€œabcโ€ string (often stored in read-only memory).
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ c language โ€บ pointer-array-array-pointer
Pointer to an Array | Array Pointer - GeeksforGeeks
Here ptr is pointer that points to an array of 10 integers. Since subscript have higher precedence than indirection, it is necessary to enclose the indirection operator and pointer name inside parentheses. The following examples demonstrate the use pf pointer to an array in C and also highlights ...
Published ย  April 30, 2025
๐ŸŒ
Study.com
study.com โ€บ computer science courses โ€บ computer science 111: programming in c
Arrays of Pointers in C Programming: Definition & Examples - Lesson | Study.com
September 27, 2021 - This code will create an integer ... to x, we can access the x using p. ... When there's a need to point multiple memories of similar data, the array of pointers can be used....
๐ŸŒ
O'Reilly
oreilly.com โ€บ library โ€บ view โ€บ understanding-and-using โ€บ 9781449344535 โ€บ ch04.html
4. Pointers and Arrays - Understanding and Using C Pointers [Book]
An array name is not a pointer. Although an array name can be treated as a pointer at times, and array notation can be used with pointers, they are distinct and cannot always be used in place of each other.
๐ŸŒ
Hero Vired
herovired.com โ€บ home page โ€บ blogs โ€บ array of pointers in c with example program
Array of Pointers in C with Example Program
September 13, 2024 - We can also create an array of pointers to store multiple addresses of different variables. Get curriculum highlights, career paths, industry insights and accelerate your technology journey.