sizeof vs strlen in C – Why sizeof(s) – strlen(s) Is 1

Two ways to measure one string, subtracted from each other. sizeof and strlen are the most-confused pair in beginner C, and this question from our C Programming Quiz App weaponizes the confusion: if you know exactly what each one counts, the subtraction is trivial — and if you don’t, every wrong option looks plausible.

The Quiz Question

char s[] = "abcd";
printf("%d", sizeof(s) - strlen(s));

What is printed by this code?

  1. 0
  2. 1
  3. 4
  4. 5

The Correct Answer: 1

sizeof(s) is the storage the array occupies: four characters plus the terminating '\0' = 5. strlen(s) counts characters up to the terminator = 4. The difference is exactly the terminator: 1. Verified on gcc 13.3 and Apple clang 21:

$ gcc -ansi -Wall -Wextra diff.c && ./a.out
sizeof(s) = 5
strlen(s) = 4
difference = 1

Why Each Wrong Answer Is Wrong

Why not 0?

Zero would mean sizeof and strlen measure the same thing. They never do for a valid string: sizeof is compile-time storage (terminator included), strlen is run-time character count (terminator excluded).

Why not 4?

4 is strlen(s) alone. If you got this, you likely mixed up which operand is which — the code subtracts strlen from sizeof, not the other way around.

Why not 5?

5 is sizeof(s) alone — the answer if the - strlen(s) part is overlooked.

When the Difference Is NOT 1

The “difference = 1” result holds only because char s[] (with no explicit size) is sized to fit the literal exactly. Change the declaration and the arithmetic changes with it:

char s[]   = "abcd";  /* sizeof 5, strlen 4 → 1  (exact fit)        */
char t[10] = "abcd";  /* sizeof 10, strlen 4 → 6 (unused tail)      */
char *p    = "abcd";  /* sizeof 8, strlen 4 → 4  (pointer, not array!) */

The last line is the dangerous one: applied to a pointer, sizeof measures the pointer variable (8 bytes on 64-bit), and the “difference” becomes meaningless. The same trap fires inside any function that receives the string as a parameter — arrays decay to pointers at the call, so sizeof can never recover a passed array’s size. The sizeof string array question drills into that side of the trap.

A Subtlety in the Quiz Code Itself: %d vs size_t

Sharp-eyed readers will notice the code prints a size_t expression with %d. Both sizeof and strlen yield size_t (unsigned, 8 bytes on 64-bit Linux), so %d is a format mismatch — and both compilers say so:

$ gcc -Wall -Wextra diff.c
warning: format '%d' expects argument of type 'int', but argument 2
has type 'long unsigned int' [-Wformat=]

On mainstream 64-bit platforms it still prints 1 (the low 4 bytes of the value land where printf reads its int), which is why the quiz answer stands — but strictly it’s undefined behavior, and the clean spellings are printf("%zu", ...) or a cast like printf("%d", (int)(sizeof(s) - strlen(s))). A quiz question with a bonus lesson in its own code.

Frequently Asked Questions

What is sizeof(s) – strlen(s) for char s[] = “abcd”?

1. sizeof counts the 5 bytes of storage including the null terminator; strlen counts the 4 visible characters. For any string that exactly fills its array, the difference is the terminator: 1.

Is sizeof minus strlen always 1?

No — only when the array exactly fits the string. char t[10] = "abcd" gives 10 − 4 = 6, and for a char * pointer sizeof measures the pointer (8 on 64-bit), giving a meaningless 4.

Can I print size_t with %d?

Not portably — sizeof and strlen return size_t, and %d expects int. Use %zu (C99) or cast the value. Compilers warn about the mismatch under -Wall.

Related Reading

Recommended Books

This question is #140 in the C Programming Quiz App — 155 questions with explanations covering arrays, strings, pointers, and more.
Download on Google Play →

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>