简介

sizeof作为C/C++关键字,基本用法是求字节大小,但仅仅这一项用法在细节上就有很多说法了

求内置类型变量的大小

有两种写法,以int a = 0的变量a为例

  • sizeof a
  • sizeof(a)

都可以求变量a的大小,但注意,该变量的大小仅与变量类型有关,而与值无关

求内置类型的大小

求类型大小时必须加上括号

例如sizeof(int)

求数组的大小

  • 当数组声明在全局sizeof处于数组声明语句的局部作用范围时,能够用sizeof(<数组名>)求数组大小
  • 当数组名经过函数传参加减常量运算后,退化为指针变量,类型大小在32位机器中为4,64位机器中为8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>

using namespace std;

int g_arr[10] = { 0 };

void func(int st_arr[])
{
cout << sizeof(st_arr) << endl;//此处退化为指针变量,输出4或8
}

int main()
{
int arr[10] = { 0 };
cout << sizeof(g_arr) << endl;//输出40
cout << sizeof(arr) << endl; //输出40
func(arr);//输出4/8
return 0;
}

求类/对象的大小

一般情况的内存对齐

为了访问效率问题,类的大小遵循内存对齐规则,计算理论大小时需考虑成员变量的大小内存对齐,而不考虑普通成员函数,这里不详细讨论

含有虚函数

C++的编译器一旦发现一个类型中有虚函数,就会为该类型生成虚函数表,每一个实例化出的对象都含有一个指向虚函数表的指针。所以sizeof求出来的值还要考虑该指针以及内存对齐等因素

没有成员变量的特殊情况

没有成员函数

这样的类型可以称为空类型,因为这样的类型实例化后不含任何信息,本来求sizeof应该是O,但考虑实际使用时,我们需将类实例化为对象,它必须在内存中占有一定的空间,否则无法使用或管理这些实例。至于分配内存,由编译器决定。但出于节省不必要的内存占用原则,理应分配最小内存单元,即1字节。正好在VisualStudio中,每个空类型的实例占用1字节的空间。

1
2
3
4
5
class A
{
//空类型
};
sizeof(A);//visual studio 中值为1

只有普通的成员函数

和上一条一样也是1字节。因为考虑实例化时,调用这些普通成员函数只需知道函数地址即可,而这些函数地址只与用户自定义的有关,而与实例化出来的对象无关,所以不会在对象中存储相关信息,不会改变其大小。

含有虚函数

实例化出的对象含有了指向虚函数的指针,所以sizeof求出来的大小为一个指针的大小,32位机器求得4字节,64位机器求得8字节