Introduction
If you've worked with the C language, you've likely encountered array types and their sometimes perplexing behavior. An array of type T[n] is distinct from a pointer type T*, but in many practical scenarios, arrays behave like pointers. This can complicate a developer's life, especially when it comes to understanding array sizes or passing arrays as function arguments.
Arrays vs. Pointers
Technically, an array T[n] represents a contiguous sequence of T values in memory. However, in most expressions, this type is immediately converted to a pointer to the first element of the array. This means that the array indexing operator arr[ix] actually operates on pointers, like *(arr + ix). A notable exception is the use of sizeof, which, when applied to an array, returns the total size of the array, i.e., sizeof(T) × n.
``c int arr[3] = {10, 20, 30}; int *arr_ptr = arr; size_t arr_size = sizeof(arr); // Returns total size size_t ptr_size = sizeof(arr_ptr); // Returns pointer size ``
Arrays as Function Arguments
When an array is passed as a function argument, it is converted into a pointer, and the array size is lost. This can lead to unexpected behaviors, as in the following example:
```c size_t foo(char buf[6]) { return sizeof(buf); // Returns pointer size }
char msg[6] = "Hello"; size_t msg_size = sizeof(msg); // Returns 6 size_t msg_size_in_fn = foo(msg); // Returns pointer size ```
To work around this issue, you can pass a pointer to the array, which preserves the length information.
```c size_t foo(char (buf)[6]) { return sizeof(buf); // Returns 6 }
char msg[6] = "Hello"; size_t msg_size_in_fn = foo(&msg); // Returns 6 ```
Similarities with Functions
Functions in C share a similar behavior with arrays in that they immediately convert to function pointers. However, dereferencing a function pointer still allows you to call the function.
``c void foo() {} (*foo)(); // Calls the function foo(); // Also calls the function ``
Why Does This Matter?
For developers, understanding these nuances is crucial for writing robust C code and avoiding hard-to-diagnose bugs. For instance, mishandling array sizes can lead to buffer overflows, one of the primary security vulnerabilities.
Conclusion
Despite their complexity, C array types are powerful and flexible. By mastering their behavior, you can leverage their efficiency while avoiding common pitfalls. Let's discuss your project in 15 minutes.
Reference
- Anselm Schueler, "C array types are weird", [anselmschueler.com](https://anselmschueler.com/blogposts/2025-c-pointers/)