size_t 是专为对象大小和数组索引设计的无符号整型,对应 sizeof 返回类型;32位平台通常为 unsigned int,64位为 unsigned long;必须用于标准库中所有非负计数场景,如 vector::size()、malloc 参数等,避免截断与警告。

size_t 就是 sizeof 的返回类型,别用 int 替代它
它不是某种“高级整数”,而是 C++ 标准为**对象大小和数组索引**量身定制的无符号整型。你写 sizeof(int)、vec.size()、strlen(s),得到的类型就是 size_t —— 强制用 int 接,轻则编译警告(-Wsign-conversion),重则在 64 位系统上截断大内存值(比如 5GB 分配被当成 1GB)。
- 32 位平台:通常是
unsigned int(4 字节) - 64 位平台:通常是
unsigned long或unsigned long long(8 字节) - 头文件:
(C++)或(C)
什么时候必须用 size_t?看函数签名和容器 API
标准库几乎把所有“非负计数”场景都绑定到了 size_t:它不是建议,是接口契约。
-
std::vector::size()、std::string::length()返回size_t -
malloc()、memcpy()、memset()的字节数参数是size_t - 循环遍历容器时,用
for (size_t i = 0; i ,避免int i和size_t比较引发隐式转换
反例:int i = vec.size(); —— 若 vec 有 50 亿元素(64 位常见),i 直接溢出变负数,后续下标访问全错乱。
打印 size_t 一定要用 %zu,否则行为未定义
用 %d 或 %u 打印 size_t 是常见错误,尤其跨平台时会崩或输出乱码。C++ 中 std::cout 没这问题,但 C 风格 printf 必须匹配:
立即学习“C++免费学习笔记(深入)”;
size_t len = strlen("hello");
printf("length: %zu\n", len); // ✅ 正确
printf("length: %u\n", len); // ❌ 可能在 64 位系统上截断高位同理,ssize_t(如 read() 返回值)必须用 %zd,它和 size_t 不兼容,不能混用。
size_t 减法陷阱:0 - 1 不是 -1,而是极大正数
它是无符号类型,所有算术都是模运算。这个特性常在边界检查中翻车:
size_t pos = 0;
if (pos > 0) {
--pos; // 这行永远不会执行
}
// 但若写成:
if (pos - 1 < vec.size()) { // pos == 0 → pos-1 == 18446744073709551615(64 位)
// 这里会意外进入!
}- 永远不要对
size_t做减法后直接比较,尤其涉及0 - 需要“向前找一个位置”时,先判断是否非零:
if (pos != 0) --pos; - 需要带符号差值(如偏移量),改用
ptrdiff_t或显式转成有符号类型(并加断言)
最易忽略的点:它看起来像“普通整数”,但语义上只适合表示“大小”和“索引”,不参与带符号计算 —— 一旦越界,不是报错,而是静默绕回,调试时极难定位。










