Skip to main content

Command Palette

Search for a command to run...

C Strings and Character Arrays: A Deep Dive

Updated
4 min read
C Strings and Character Arrays: A Deep Dive
D

I'm an Engineer


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:

  1. What is a C String?

  2. Character arrays vs String Literals

  3. Modifiability and read-only memory

  4. Memory Layout

  5. Common pitfalls

  6. 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 StyleModifiableMemory typeUse Case
char str[] = “abc”YesStackLocal mutable string
char str* = “abc”NoRead-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 binary

  • str holds the address of the first character ‘H’

  • Does not allow any modification

In contrast:

char str[] = "Hello";
  • Stores 3-byte array on the stack

  • Allows 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

  1. 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;
     }
    
  2. strcpy(des, src)

    Copies the string from src to dest, 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;
     }
    
  3. strcat(des, src)

    Appends src string to the end of des string.

     #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;
     }
    
  4. 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 const where applicable

  • Avoid 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.


27 views

More from this blog

The Engineering Hub

11 posts

knowledge sharing portal...