认识 size_t 和指针类型的大小

1.简介

size_t 是 C 语言中用于表示对象大小的无符号整数类型。它是标准库 <stddef.h> 中定义的类型,通常用于与 sizeof 运算符一起使用,以表示对象的大小。

在 C++ 中被定义在 cstddef 头文件,该头文件文件是 C 标准库的头文件 stddef.h 的 C++ 版。

size_t 是为了表示对象大小而引入的类型。它的引入是为了提供一种在不同系统上都能够一致表示对象大小的方式。

2.大小

size_t 的大小是由编译器和目标系统决定的,它反映了能够表示内存对象大小的最大值。在不同的系统和编译器中,size_t 可能会有不同的大小。

一般情况下,在 32 位系统中 size_t 是 4 字节的,而在 64 位系统中,size_t 是 8 字节的,这样利用该类型可以增强程序的可移植性。

上面的描述看似很有道理,但是很多人在测试的时候发现,为什么测试环境明明是 64 位的系统,sizeof(size_t) 的值却等于 4 呢?而不是原本预期的 8。

本机环境是 Win7 64bits,使用 VS2017 来验证。

本机系统类型:
这里写图片描述

测试代码:

cout << "sizeof(size_t)=" << sizeof(size_t) << endl;

输出结果:

sizeof(size_t)=4

为什么会这样,我之前一直也弄不明白。原来网上说的 size_t 的大小由系统的位数决定并不准确。那 size_t 的大小究竟由什么决定呢?

先看一下我刚刚测试代码的 VS2017 的编译配置。配置如下:

这里写图片描述
红色框中的Win32表示的是什么意思呢?原来Win32表示生成的程序是32bits。32bits的程序既可以在Windows 32bits的系统下运行,也可以在Windows 64bits的系统下运行。所以,我们配置生成的程序是32bits的,因此 size_t 就是 unsigned int 类型,大小为4个字节。

VC++ 中关于 size_t 的定义如下:

#ifdef  _WIN64
typedef unsigned __int64    size_t;
#else
typedef _W64 unsigned int   size_t;
#endif

其大概意思就是 size_t 要么是 unsigned int,要么是 unsigned long int,那么按照上面的推理,修改编译选项为 x64,生成 64bits 的程序,size_t 的类型是不是就变成了 unsigned long int 了呢?我们来验证一下。

VS2017的编译配置更改如下:
这里写图片描述

同样的测试代码:

cout<<"sizeof(size_t)="<<sizeof(size_t)<<endl;

输出结果为:

sizeof(size_t)=8

正如预期的一样,size_t 变成了 unsigned long int,占用 8 字节的内存空间。

size_t 的大小并非像很多网上描述的那样,其大小是由系统的位数决定的。size_t的大小是由你生成的程序类型决定的,只是生成的程序类型与系统的类型有一定关系。32bits的程序既可以在64bits的系统上运行,也可以在32bits的系统上运行。但是64bits的程序只能在64bits的系统上运行。然而我们编译的程序一般是32bits的,因此size_t的大小也就变成了4个字节。

3.指针的大小

指针用于存放地址,其大小有机器字长决定,如果是32位机器就是4字节的,如果是64位机器就是8字节的。

这里的32位机器和64位机器指的是什么呢?CPU的架构决定了机器的类型,如果CPU是x86架构,那么就是32位的CPU,当然并非所有的x86架构的CPU都是32位的,比如intel的8086和8088就是16位的CPU。如果CPU是x86-64的架构,那么就是64位的CPU。

CPU的位数由其字长决定,字长表示CPU在同一时间中能够处理二进制数的位数叫字长。字长是由CPU中寄存器的位数决定的,并非由数据总线的宽度决定的,只是数据总线的宽度一般与CPU位数相一致。

系统的位数依赖于CPU的位数,即32位的CPU不能装64位的系统,但是现在(2018年)的CPU基本上都是x86-64的CPU,都支持64位的系统。正如上面的讨论,如果编译生成的程序不是64位的,那么指针的大小依然是4个字节。

验证一下。将 VS2017 编译配置改为:
这里写图片描述
测试代码:

cout << "sizeof(char*)=" << sizeof(char*) << endl;

输出结果:

sizeof(char*)=4

更改编译配置,生成64位的程序,我们将得到预想的结果:

sizeof(char*)=8

4.ssize_t

与 size_t 对应的无符号类型是 ssize_t。

ssize_t 是有符号整数类型,通常用于表示系统调用(如 read() 和 write())返回的字节数,以及其他可能返回负值的情况。在许多系统中,ssize_t 的大小与 ptrdiff_t 类型相同。


参考资料

size_t - 百度百科

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值