Nearby lessons

64 of 124

C - String Declaration

How to declare a string in C — a fixed-size char array versus a char * pointer to a string literal, and the crucial difference in whether the contents can be modified.

Form 1 — The char Array

This reserves a block of writable bytes that you own. It is the form to use whenever the text will change:

Example01
CCode Cell
1#include <stdio.h>
2#include <string.h>
3 
4int main()
5{
6 char name[50]; /* 50 writable bytes, contents undefined */
7 
8 strcpy(name, "Rahul"); /* fill it */
9 printf("name : %s\n", name);
10 printf("capacity: %zu bytes\n", sizeof(name));
11 printf("used : %zu characters\n", strlen(name));
12 
13 strcpy(name, "Priya"); /* can be changed freely */
14 printf("changed : %s\n", name);
15 return 0;
16}
Output
name    : Rahul
capacity: 50 bytes
used    : 5 characters
changed : Priya

Form 2 — The char Pointer

A char * holds the address of text. When it points at a string literal, that text usually lives in a read-only section of the program:

Example02
CCode Cell
1#include <stdio.h>
2#include <string.h>
3 
4int main()
5{
6 char *msg = "Hello"; /* points to a literal */
7 
8 printf("msg : %s\n", msg);
9 printf("length : %zu\n", strlen(msg));
10 printf("pointer : %zu bytes\n", sizeof(msg)); /* the POINTER size */
11 
12 msg = "Goodbye"; /* repointing is fine */
13 printf("repointed: %s\n", msg);
14 return 0;
15}
Output
msg     : Hello
length  : 5
pointer : 8 bytes
msg     : Goodbye

The Critical Difference — Modifiability

You can change the characters of an array. You must not change the characters of a string literal, even through a pointer:

Example03
CCode Cell
1#include <stdio.h>
2 
3int main()
4{
5 char arr[] = "Hello"; /* a writable COPY of the literal */
6 char *ptr = "Hello"; /* points AT the literal itself */
7 
8 arr[0] = 'J'; /* fine */
9 printf("arr = %s\n", arr);
10 
11 /* ptr[0] = 'J'; UNDEFINED BEHAVIOUR - usually crashes */
12 printf("ptr = %s (left unchanged)\n", ptr);
13 return 0;
14}
Output
arr = Jello
ptr = Hello  (left unchanged)

Why the Pointer Version Crashes

In simple words: char arr[] = "Hello"; copies the text into your array — you own it, so you can edit it. char *ptr = "Hello"; does not copy anything; it just records where the compiler's literal lives. That memory is typically marked read-only, so writing to it triggers a segmentation fault.

Because the mistake is so easy to make, always write const char * when you only intend to read. Then the compiler catches the error instead of your users:

Example04
CCode Cell
1#include <stdio.h>
2 
3int main()
4{
5 const char *msg = "Hello"; /* compiler now protects it */
6 
7 /* msg[0] = 'J'; ERROR: assignment of read-only location */
8 
9 printf("%s\n", msg);
10 return 0;
11}
Output
Hello

Array vs Pointer — Side by Side

char s[] = "Hi";char *s = "Hi";
What is storedA writable copy of the textAn address only
Memory locationStack (if local)Read-only data section
sizeof(s)3 (text + \0)8 (pointer size)
Modify charactersYesNo — undefined behaviour
Repoint to other textNoYes
Best forBuffers you will editFixed messages you only read

Sizing the Array Correctly

Always reserve one byte more than the longest text you expect:

Example06
CCode Cell
1#include <stdio.h>
2#include <string.h>
3 
4int main()
5{
6 char a[6] = "Hello"; /* 5 + 1 = exactly right */
7 char b[20] = "Hello"; /* room to grow */
8 char c[] = "Hello"; /* compiler counts: 6 */
9 
10 printf("a: %s (sizeof %zu)\n", a, sizeof(a));
11 printf("b: %s (sizeof %zu)\n", b, sizeof(b));
12 printf("c: %s (sizeof %zu)\n", c, sizeof(c));
13 
14 strcat(b, " World"); /* only b has room for this */
15 printf("b after strcat: %s\n", b);
16 return 0;
17}
Output
a: Hello (sizeof 6)
b: Hello (sizeof 20)
c: Hello (sizeof 6)
b after strcat: Hello World

An Array of Strings

To hold several strings you need a 2D char array, or an array of pointers:

Example07
CCode Cell
1#include <stdio.h>
2 
3int main()
4{
5 /* 2D array - each name gets 20 writable bytes */
6 char names[3][20] = {"Rahul", "Priya", "Amit"};
7 
8 /* array of pointers - read-only, no wasted space */
9 const char *cities[3] = {"Delhi", "Mumbai", "Chennai"};
10 int i;
11 
12 for (i = 0; i < 3; i++)
13 printf("%-8s from %s\n", names[i], cities[i]);
14 return 0;
15}
Output
Rahul    from Delhi
Priya    from Mumbai
Amit     from Chennai

Common Mistakes

  • Modifying a string literalchar *s = "Hi"; s[0] = 'B'; crashes at runtime.
  • Forgetting the terminator's bytechar s[5] = "Hello"; has no room for \0.
  • Using sizeof on a char * — gives 8, the pointer size, not the text length.
  • Copying into an uninitialised pointerchar *s; strcpy(s, "Hi"); writes to a random address.
  • Returning a local array from a function — the memory is gone once the function returns.
The one-character difference that decides everything: char s[] gives you your own writable copy; char *s gives you a view of someone else's constant. Adding const to the pointer form turns a runtime crash into a compile-time error.
📝 Key Takeaways
  • char s[50]; reserves 50 writable bytes.
  • char *s = "text"; points at a read-only string literal.
  • Array form: modifiable. Pointer-to-literal form: do not modify.
  • Always leave room for the \0 when sizing an array.
  • Use const char * when you only need to read the string.

🧠 Test Your Knowledge

4 Questions
Progress: 0 / 4