Array of Pointers in C: Syntax and Working Examples

Three pointer array slots connect to three separate integer objects.

An array of pointers in C stores pointer values as its elements. Each element can hold the address of a different object. For example, int *items[3] declares an array of three pointers to int.

Declaring the array does not automatically create three int objects. Initialize each pointer with a valid address before dereferencing it.

Point to existing integers

#include <stdio.h>

int main(void)
{
    int first = 10;
    int second = 20;
    int third = 30;
    int *items[] = {&first, &second, &third};
    size_t count = sizeof items / sizeof items[0];

    *items[1] = 25;

    for (size_t i = 0; i < count; ++i) {
        printf("items[%zu] points to %d\n", i, *items[i]);
    }

    printf("second is now %d\n", second);
    return 0;
}

Output:

items[0] points to 10
items[1] points to 25
items[2] points to 30
second is now 25

items[1] is the pointer to second. Applying the * operator accesses an integer, so this assignment changes second itself. The integer objects continue to exist throughout this function.

Store pointers to strings

For a list of string literals, use pointers to const char:

#include <stdio.h>

int main(void)
{
    const char *languages[] = {"C", "C++", "Python"};
    size_t count = sizeof languages / sizeof languages[0];

    for (size_t i = 0; i < count; ++i) {
        printf("Index %zu: String = \"%s\"\n", i, languages[i]);
    }

    return 0;
}

Output:

Index 0: String = "C"
Index 1: String = "C++"
Index 2: String = "Python"

The backslashes before the inner quotation marks are required in the C source. Without them, the format string will end prematurely and the example will not compile.

Do not modify string literals. Using const char * lets the compiler diagnose attempts to write through these pointers. You can still reassign an array element to point to another string.

If you need characters you can change, use a writable character array. Making a pointer to a string literal does not give you a writable copy.

Array of pointers vs pointer to an array

Declaration Meaning
int *p[3]; Three pointer elements, each pointing to an int
int (*p)[3]; One pointer to an array of three integers
int values[3]; Three integer elements

Inserting parentheses changes the declaration. In int (*p)[3], p is a pointer, whereas in int *p[3], p is an array.

An array of pointers differs from a rectangular two-dimensional array. For example, char names[3][16] stores three rows of 16 characters each. With const char *names[3], the elements are pointers and the strings live elsewhere. Do not pass one representation to a function expecting the other.

Memory size and addresses

Use sizeof items to measure the pointer array and sizeof items[0] to measure one element. The array's size does not include separately stored objects reached through its pointers.

Pointer size depends on the implementation. Do not assume that every pointer occupies eight bytes or that its printed address identifies a physical RAM location.

To print an object pointer, use %p and convert its value to void *: printf("%p\n", (void *)items[0]);. The address and its formatting can vary, so do not use a fixed address as expected output.

Common mistakes

Initialize each element before using it, check the index, and confirm that the pointed-to object is still alive. Storing an address in an array does not extend the object's lifetime. Do not dereference a pointer after its target object has gone out of scope or been freed.

If pointed-to objects are allocated dynamically, determine who owns the allocation and is responsible for freeing it. Do not use free on the local integers or string literals used in this example. See dynamic memory examples for storage that is allocated.

Is an array of pointers the same as int **?

No. An array object and a pointer object are different. In many expressions, an array of int * converts to a pointer to its first element, with type int **. That conversion does not turn the original array into a pointer variable.

See sections 6.3, 6.4.5, and 6.7.6 of the C11 committee draft for pointer conversions, string literals, and array declarations. Run the complete examples in the online C compiler, then change an integer through a different pointer element.

Related examples