C Strings and Character Arrays: A Deep Dive

C, the language of systems programming, offera a minimal but a powerful way to handle text — using character arrays and null terminated strings. Unlike high level languages that abstract away the complexity, C exposes the raw memory model, making it more powerful and error prone.
In this post, we will walk through:
What is a C String?
Character arrays vs String Literals
Modifiability and read-only memory
Memory Layout
Common pitfalls
Useful standard functions
1. What is a C String?
In C, a string is simply an array of characters terminated by a null character (‘/0’)
char str[] = "Hello";
This declares a a 6 byte character array: ‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘\0’. A valid C string must be null terminated.
2. Character Arrays vs String Literals
There are two main ways to define strings in C:
A. Character Arrays (modifiable)
char str[] = "Hello";
str[0] = 'M'; //Allowed
Memory Layout:
Allocated on the stack (local scope)
Writable
Size is
strlen(“Hello”) + 1 = 6 bytes
B. Pointer to String Literal (read-only)
char* str = "Hello";
str[0] = 'M'; //not allowed. Undefined behavior
Memory Layout:
Points to read-only memory segment (typically
.rodata)Attempting to modify it leads to undefined behavior
It may result in segmentation fault on some systems
Use const when declaring read-only string literals to avoid accidental write operation.
const char* str = "Hello";
3. Modifibility and Read-only memory
| Declaration Style | Modifiable | Memory type | Use Case |
char str[] = “abc” | Yes | Stack | Local mutable string |
char str* = “abc” | No | Read-only (.rodata) | Constant Strings |
4. Memory Layout
Let’s breakdown to anayze how this works:
char* str = "Hello";
A string
“Hello\0”is stored at read-only section of the binarystrholds the address of the first character‘H’Does not allow any modification
In contrast:
char str[] = "Hello";
Stores
3-bytearray on the stackAllows modification
5. Common Pitfalls
A. Forgetting Null Terminator
char str[3] = {'O', 'K', '!'}; //Not a valid C String
Calling strlen(str) leads to undefined behavior as there is no null terminatior ‘\0’
Right way:
char str[4] = {'O', 'K', '!', '\0'};
B. Modifying Read-Only Memory
char* str = "Hello";
str[0] = 'M'; // Segmentation fault on most systems
Use char str[] = “Hello”; if you want to modify it.
C. Buffer Overflow
char str[5];
strcpy(str, "Hello");
Compiling the above code will give a message writing 6 bytes into a region of size 5 overflows the destination. Always ensure the destination buffer is large enough. Preferably use strncpy carefully
char str[5]
strncpy(str, "Hello", sizeof(str) - 1);
str[sizeof(str) - 1] = '\0'; //Ensure Null Termination
Note: In the above code: The string "Hello" is longer than the array size, so it will be truncated. The last character will be replaced with null terminator. This will result in str containing "Hell" and not "Hello".
6. Useful Standard Functions
strlen(str)Returns the length of the string excluding the null terminator (
‘\0’)#include <stdio.h> #include <string.h> int main() { char str[] = "Hello"; printf("String Length : %zu\n", strlen(str)); // Output-> String Length: 5 return 0; }strcpy(des, src)Copies the string from
srctodest, including the null terminator.#include <stdio.h> #include <string.h> int main() { char src[] = "Hello"; char des[10]; strcpy(des, src); printf("Copied String: %s\n", des); // Output-> Copied String: Hello return 0; }strcat(des, src)Appends
srcstring to the end ofdesstring.#include <stdio.h> #include <string.h> int main() { char des[20] = "Hello"; char src[] = "World; strcat(des, src); printf("Concatenated String: %s\n", des); // Output-> Concatenated String: Hello World return 0; }strcmp(s1, s2)Compares two strings:
Returns 0 if they are equal
Negative value if s1 < s2
Positive values if s1 > s2
#include <stdio.h>
#include <string.h>
int main() {
char s1[] = "abc";
char s2[] = "abd";
int result = strcmp(s1, s2);
printf("Comparison Result: %d\n, result); // Output -> Negative value
}
Best Practices
Use
constwhere applicableAvoid writing to string literals
Always null-terminate your strings
Watch out for buffer overflows
Conclusion
C strings are simple but comes with caveats. Understanding how memory and modifiability works helps avoid running into common pitfalls that leads to bugs and crashes.




