What is size_t in C?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
size_t is the unsigned integer type used by C to represent object sizes and counts returned by operations such as sizeof. You see it throughout the standard library because it is the type meant to hold the size of any object the implementation can represent.
Core Sections
What size_t actually means
size_t is not a keyword like int or long. It is a typedef defined by the implementation, usually through headers such as <stddef.h>, <stdio.h>, or <stdlib.h>. The exact underlying unsigned integer type can differ by platform.
The important guarantee is semantic, not cosmetic: it is wide enough to represent the size in bytes of any single object the implementation supports.
Notice the %zu format specifier. That is the correct way to print a size_t value with printf.
Where you encounter size_t
The type appears in several standard library APIs because those APIs deal with sizes, lengths, or element counts.
Examples include:
- '
sizeof' - '
strlen' - '
malloc,calloc, andrealloc' - '
freadandfwrite'
Using size_t here matches the API and avoids unnecessary signed-to-unsigned conversions.
Why it is better than plain int for sizes
Many beginners reach for int for loop counters and lengths because it is familiar. That works until the value range or platform assumptions stop matching reality. size_t communicates intent directly: this value represents a size or count that came from memory layout or container length.
On 64-bit systems, size_t is often wider than int. Even when the current program will never allocate billions of elements, using the library’s natural size type prevents mismatched arithmetic and warning noise.
Watch signed-versus-unsigned behavior
The main sharp edge is that size_t is unsigned. Unsigned arithmetic can underflow instead of becoming negative.
That does not print -1. It wraps to a very large positive value. This is why reverse loops with size_t need careful structure.
A safer reverse loop pattern is:
This avoids the classic i >= 0 bug, which is always true for an unsigned type.
Use it where the API expects it
When a standard function returns size_t, store the result in size_t unless you have a strong reason not to. This prevents narrowing and conversion issues.
Matching the type also makes your code clearer to other C programmers because the variable immediately signals “this is a size-like quantity.”
Common Pitfalls
- Treating
size_tas if it were always the same underlying type on every platform. - Printing a
size_tvalue with%dor%luinstead of the correct%zuformat specifier. - Mixing
intandsize_tfreely in comparisons and loops, which often creates warnings or subtle bugs. - Writing reverse loops such as
for (size_t i = n - 1; i >= 0; --i), which do not work the way signed loops do. - Assuming
size_tmeans “large integer” in general, even though its real purpose is representing sizes and counts.
Summary
- '
size_tis the standard unsigned type for object sizes and related counts in C.' - It is a typedef chosen by the implementation, not a fixed built-in type.
- Standard library functions that deal with lengths and memory sizes use it heavily.
- Use
%zuto print it and be careful with unsigned arithmetic in reverse loops. - Prefer
size_twhen the value conceptually represents a size, length, or element count.

