The Trouble with Array Decay

Array decay has nothing to do with too much sugar in your code or poor brushing habits. No, it’s a hot topic in C programming, and a source of confusion.

Array decay is a byproduct of the tenuous relationship between arrays and pointers in the C language. It might be the reason why some programmers avoid pointers because the two are similar — to a degree.

🗸 Arrays are not pointers.

🗸 Pointers are not arrays.

A connection exists between pointers and arrays, however, which is what array decay describes. The first element of an array, truly the array name itself, represents an address. The behavior is shown in the following code:

2025_09_06-Lesson-a.c

#include <stdio.h>

int main()
{
    char str1[] = "I am string one!";
    char *str2 = "I am string two!";

    puts(str1);
    puts(str2);

    return 0;
}

Variable str1[] is a character array, a string. So is variable str2, though it’s declared as a pointer. Strings are declared either way in C. With str1[], you use array notation to access the individual characters (elements). With str2, pointer notation is used. (Also, str2 has its own quirks, which I discuss here.)

Both variables are used in the same manner with the puts() function to output the strings:

I am string one!
I am string two!

The compiler sees both str1[] and str2 as addresses, the location in memory where a string is stored. This effect is how array decay works: The first element in an array “decays” to a pointer. The element isn’t specified directly. If you try the statement puts(str1[0]), the compiler generates a warning as str1[0] is a single character and not a string. Running the program results in Bad Things happening.

The following code also shows array decay in action, where the array is assigned to a pointer:

2025_09_06-Lesson-b.c

#include <stdio.h>

int main()
{
    int array[] = { 10, 20, 30, 40 };
    int *ptr;

    ptr = array;
    printf("%d\n",*ptr);

    return 0;
}

Due to the array decay, the statement ptr = array works; the array’s base address is saved in int pointer ptr. Further, the pointer is used in the printf() statement to output the value of the array’s first element, 10.

The code could further use the pointer to reference other elements in the array. For example, *(ptr+3) references the fourth array element, 40.

This witchery doesn’t work in reverse. You cannot use an array to dig into a pointer’s buffer. After all, the effect is called “array decay” and not “whacky pointer things.”

Where array decay comes in handy is when dealing with arrays and functions. I explore this aspect of array decay in next week’s Lesson.

2 thoughts on “The Trouble with Array Decay

  1. Thank you for providing another interesting article! (Havenʼt posted in a while… but I always make sure to read your blog posts.)

    “This witchery doesnʼt work in reverse. You cannot use an array to dig into a pointer’s buffer.”

    True, one cannot use an array… while somewhat unusual, one can however declare a pointer to an array of a specific size:

    int (*ind_arr) [4] = &array; /* will work in C89 */
    int elem = (*ind_arr) [3];
    printf ("%d\n", elem); /* (will print ‘40␤’) */

    Relying on C99ʼs variable-length array (VLA) syntax, itʼs even possible to do this with array bounds whose value will only be known at runtime:

    int a = 2, b = 2; /* requires C99 VLAs */
    int (*ind_arr) [a][b] = (int (*) [a][b])&array;
    int elem = (*ind_arr) [1][0];
    printf ("%d\n", elem); /* (will print ‘30␤’) */

    Granted, this is now a really unusual thing to do. (Outside of code for numerical libraries, itʼs probably best to stay away from such shenanigans… not least because not all compilers support VLAs.)

  2. Fascinating! I know that you can use the (*var) notation for allocated structures, but this is a great trivial tidbit! Thank you again!

Leave a Reply