In-depth Analysis of char* vs char[] in C: Memory Layout and Type Differences

Nov 28, 2025 · Programming · 9 views · 7.8

Keywords: C programming | character pointers | character arrays | memory layout | type system

Abstract: This technical article provides a comprehensive examination of the fundamental distinctions between char* and char[] declarations in C programming. Through detailed memory layout analysis, type system explanations, and practical code examples, it reveals critical differences in memory management, access permissions, and sizeof behavior. Building on classic Q&A cases, the article systematically explains the read-only nature of string literals, array-to-pointer decay rules, and the equivalence of pointer arithmetic and array indexing, offering C programmers thorough theoretical foundation and practical guidance.

Basic Declarations of Character Pointers and Character Arrays

In C programming, character pointers char * and character arrays char[] are two common approaches for handling strings, but they differ fundamentally in memory management and type semantics. Consider the following two declarations:

char *array = "One good thing about music";
char array[] = "One good thing about music";

The first declaration creates a pointer to a string literal. The string literal "One good thing about music" typically resides in a read-only data segment and contains 27 characters (including the terminating null character \0). The pointer array stores the address of the first character of this string, so modifying the string content through the pointer may lead to undefined behavior.

The second declaration defines a character array and copies the content of the string literal into the array's storage during initialization. The array array allocates 31 bytes (calculated based on the string length) on the stack or in static storage, and its content is readable and writable. This declaration is essentially equivalent to:

char array[] = {'O','n','e',' ','g','o','o','d',' ','t','h','i','n','g',' ','a','b','o','u','t',' ','m','u','s','i','c','\0'};

Memory Layout and Type System Analysis

From a memory layout perspective, the pointer declaration is represented as follows:

+-------+     +------------------------------+
| array | --> | "One good thing about music" |
+-------+     +------------------------------+

Here, array is a pointer variable occupying one machine word (e.g., 4 or 8 bytes) and points to the starting address of the string literal. In contrast, the array declaration directly contains the string content in memory:

+------------------------------+
| "One good thing about music" |
+------------------------------+

The array name array decays to a pointer to its first element in most expressions, i.e., &array[0]. This decay rule allows arrays and pointers to be used interchangeably in many contexts, but the key distinction lies in the type system:

Array-to-Pointer Decay and Access Equivalence

The C standard specifies that array types are automatically converted to pointers to their first elements in most expressions. This characteristic makes the following access methods entirely equivalent:

char array[] = "Foobar";
char fourth_char1 = array[3];    // Array indexing
char fourth_char2 = *(array + 3); // Pointer arithmetic
char fourth_char3 = *(3 + array); // Commutativity applied
char fourth_char4 = 3[array];     // Unconventional but legal syntax

This equivalence stems from the definition of pointer arithmetic: array[i] is defined as *(array + i), and since addition is commutative, *(i + array) is also valid, leading to the seemingly odd syntax i[array].

Practical Considerations in Programming

Understanding these differences is crucial in practical development:

  1. Read-only nature of string literals: String literals accessed via pointers should not be modified, as this may cause program crashes
  2. Memory management: Arrays are allocated on the stack with automatic lifetime management; pointers may require dynamic memory allocation
  3. Function parameter passing: Arrays always decay to pointers when passed as function parameters, so sizeof cannot retrieve the array size within functions
  4. Type safety: Although char* and char[] are interchangeable in some contexts, compiler type checking rules differ for them

Referencing string handling in other programming languages, such as string-to-character-array conversion in LabVIEW, although implementations vary, similar considerations regarding memory layout and access patterns apply. In C, the choice between pointer and array declarations should depend on the specific application scenario: use arrays when string content needs modification, and pointers when only reading is required to save memory copying.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.