A recently posted question on Stack Overflow highlighted a common misconception about the role of pointers and arrays held by many programmers learning C.
The confusion stems from a misunderstanding concerning the role of pointers and strings in C. A pointer is an address in memory. It often points to an index in an array, such as in the function strtoupper
in the following code:
my_str
is actually a pointer to a block of memory holding chars. This allows us to use address math to access indices of the array and modify them using the dereference operator. In fact, an array index such as my_str[3]
is identical to the expression *(my_str + 3)
.
However, if my_str
is declared as a char pointer to the string literal “hello world†rather than a char array, these operations fail:
Let’s explore the difference between the two declarations.
In the compiled program, it is likely that “hello world†is stored literally inside the executable. It is effectively an immutable, constant value. Pointing char *a
to it provides the scope with read-only access to an immutable block of memory. Therefore, attempting to assign a value might cause other code that points to the same memory to behave erratically (read this response to the above post on Stack Overflowfor an excellent explanation of this behavior.)
The declaration of char b[]
instead declares a locally allocated block of memory that is then filled with the chars, “hello worldâ€. b
is now a pointer to the first address of that array. The complete statement, combining the declaration and assignment, is shorthand. Dispensing with the array size (e.g., char
instead of char[12]
) is permitted as the compiler is able to ascertain its size from the string literal it was assigned.
In both cases the pointer is used to access array indices:
However, only with b
is the program able to modify the values in memory, since it is explicitly copied to a mutable location on the stack in its declaration: