thecodex.expert · The Codex Family of Knowledge
C

Arrays and Strings

There is no string type in C at all — a string is just a convention: a char array that happens to end with a zero byte, and every string function trusts that byte is actually there.

C17 / C23 Null-terminated, no bounds checking Last verified:
Canonical Definition

A C array is a fixed-size, contiguous block of same-typed elements with zero automatic bounds checking — reading or writing past the end is legal C syntax that produces undefined behavior, not a caught error. A string is simply a char array by convention, terminated by a null byte (\0) marking where it ends; string.h functions like strlen and strcpy work by scanning forward until they find that byte, which is also why a missing null terminator causes them to keep reading (or writing) past the buffer's actual end.

Strings are char arrays with a hidden extra byte

The 6-character array below actually needs 6 bytes: 5 letters plus the null terminator the compiler adds automatically for a string literal — forgetting to budget space for that byte in a manually-sized buffer is a classic, real bug.

Cstrings_basic.c
char name[6] = "hello";   // 'h','e','l','l','o','\0' — exactly fills 6 bytes
printf("%s\n", name);       // printf scans until it hits the \0

char broken[5] = "hello";  // COMPILE WARNING (or worse): no room for the \0 at all

Arrays decay to pointers when passed to a function

Inside the function, size has no way to know the array's original length — it only ever sees a pointer to the first element, which is why array length must always be passed as a separate parameter in C.

Carray_decay.c
void printArray(int arr[], int size) {   // arr is really just int*, size info is LOST
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
}

int numbers[5] = {1, 2, 3, 4, 5};
printArray(numbers, 5);   // must pass the length separately — the array itself can't tell you

The real danger: buffer overflows

strcpy has no idea how big dest actually is — if source is longer than dest's capacity, strcpy happily writes past the buffer's end anyway, corrupting whatever memory happens to sit right after it. This exact class of bug has historically been one of the most common, serious sources of real security vulnerabilities in C programs.

Cbuffer_overflow.c
char dest[5];
char *source = "this string is way too long for dest";
strcpy(dest, source);   // UNDEFINED BEHAVIOR — writes far past dest's 5 bytes

// safer alternative, bounded by the destination's actual size:
strncpy(dest, source, sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0';   // strncpy doesn't guarantee null-termination either

Sources

1
ISO/IEC 9899 (C Standard), "Array and string usage," cppreference.com/w/c/string/byte.