sizeof 精要

原创 2012年03月29日 08:33:39

要理解 sizeof 的要点,首先要明白字节对齐。

一. 字节对齐

但一般而言,满足以下两点个:
1) 结构体每个成员相对于结构体首地址的偏移量都是本成员大小的整数倍,如不满足则加上填充字节;
2) 结构体的总大小为结构体最宽的基本类型成员大小的整数倍,如不满足则在最后加上填充字;

struct A {
	int a;
	char b;
	short c;
};

struct B {
	char b;
	int a;
	short c;
};

int main()  
{  
    A aa = {0xffffffff, 0x11, 0xffff};

    B bb = {0x11, 0xffffffff, 0xffff};

    int xx = sizeof(aa);
    int yy = sizeof(bb);

    return 0;  
}  

分析A:

首先第一个 int 为 4 。----

其次 char 为 1,char 成员相对于首地址的偏移量为4, 4是char 本身大小 1 的整数倍,所以可以接着安置。-----

然后 short 为2,short 成员相对于首地址的偏移量为5,5不是short 本身大小 2 的整数倍,所以在填充到6。-----X--

最后计算总大小,int 4+char 1+填充 1+ short 2 = 8,8是最宽int 4 的整数倍。所以后面不再填充。

调试结果如下:

分析B:

首先第一个 char为 1 。-

其次 int 为 4,int 成员相对于首地址的偏移量为 1, 1显然不是 int 本身大小 4 的整数倍,所以要填充到4。-XXX

然后 short 为2,short 成员相对于首地址的偏移量为 8,8 是short 本身大小 2 的整数倍,所以不需要填充。-XXX------

最后计算总大小,char 1 + 填充 3 + int 4 +  short 2 = 10,10不是最宽 int 4 的整数倍。所以后面还要再填充到12。-XXX-----XX

调试结果如下:



二. sizeof 相关

1. sizeof 计算字符串长度

char str1[20] = "0123456789";
char str2[] = "0123456789";

int a = sizeof(str1); //20
int b = sizeof(str2); //11, 注意要还要加上 '\0'

int c = strlen(str1); //10, 注意 strlen 参数只能是char*, 且必须以'\0'结尾
计算字符串时,sizeof 要计算 '\0';而strlen 不计算'\0'

2. sizeof 计算含有虚函数的类对象大小

class A
{
public:
    A(int x):a(x) {}

    virtual void print()
    {
      cout << "A" << endl;
    }

private:
    int a;
};

class B:public A
{
public:
    B(int x):A(x-1),b(x)
    {}

    virtual void print()
    {
      cout << "B" << endl;
    }

private:
    int b;
};

sizeof(A) == 8; // int 4 + 虚表指针 4 = 8
sizeof(B) == 12; // int 4 + int 4 + 虚表指针 4 = 12
可以看出,含虚函数(不管含多少个虚函数)的类,会只有一个虚表指针。普通的成员函数不占用字节。

3. sizeof 计算含静态成员的类大小

class A
{
public:
    int a;
    static int b;
};
int A:b = 10;

sizeof(A) == 4; //只计算 int a
静态成员的空间不在类的实例中,而是像全局变量一样在静态存储区中,被类共享,所在不计算在内。

4. sizeof 计算联合体大小

uniton u1
{
    double a;
    int b;
};

uniton u2
{
    char a[13];
    int b;
};

sizeof(u1) == 8;  //联合体大小取所有成员中最大的一个成员的大小

sizeof(u2) == 16; //最大成员为13,但要按 int 的对齐方式(也就是要能整除 int) 
计算联合体时,取最大的成员,但也要考虑字节对齐。

5. sizeof 其它方面
基本数据类型,char 1, shour 2, int 4, double 8, 指针 4
函数参数,看成指针 4

sizeof精要

要理解 sizeof 的要点,首先要明白字节对齐。 一. 字节对齐 但一般而言,满足以下两点个: 1) 结构体每个成员相对于结构体首地址的偏移量都是本成员大小的整数倍,如不满足则加上...
  • nuptwanglei
  • nuptwanglei
  • 2015年05月01日 10:44
  • 179

sizeof 精要

 要理解 sizeof 的要点,首先要明白字节对齐。 一. 字节对齐 但一般而言,满足以下两点个: 1) 结构体每个成员相对于结构体首地址的偏移量都是本成员大小的整数倍,如不满足则加上...
  • tyy_ing
  • tyy_ing
  • 2013年11月21日 13:12
  • 453

《JavaScript面向对象精要》

这本书应该是 14 年(或15年)买的,那时人比较傻,看不明白,匆匆看了几十页就束之高阁了,但是一有点很确定,这是本好书。今天终于来到了这里,感觉过了一道坎。引用类型就是对象,对象就是引用类型类型分原...
  • wozaixiaoximen
  • wozaixiaoximen
  • 2017年01月08日 15:34
  • 411

Unity Shader入门精要读书笔记第一篇

渲染流水线 计算机需要从一系列的顶点数据,为力等信息处罚,将这些信息最终转换成一张人眼可以看到的图像。 这一渲染过程分成三个阶段: 1. 应用阶段 :有开发者主导的阶段。例如,开发者使用了哪些...
  • ndc1992
  • ndc1992
  • 2016年07月08日 10:55
  • 1080

JavaScript面向对象精要(一)

传统面向对象的语言几大特征:封装、继承、多态,在JavaScript中并不适用。JavaScript的弱类型特征允许你用比其他语言更少的代码完成同样的任务。无需提前设计好类再进行编码。需要一个具有某个...
  • ligang2585116
  • ligang2585116
  • 2017年01月08日 15:16
  • 3300

Unity Shader入门精要学习笔记 - 第4章 学习 Shader 所需的数学基础

笛卡尔坐标系 1)二维笛卡尔坐标系 在游戏制作中,我们使用的数学绝大部分都是计算位置、距离、角度等变量。而这些计算大部分都是在笛卡尔坐标系下进行的。 一个二维的笛卡尔坐标系包含了两个部分的信息: 一个...
  • u010848412
  • u010848412
  • 2017年05月02日 16:21
  • 1042

≪统计学习精要(The Elements of Statistical Learning)≫课堂笔记(四)

照例继续本周笔记。这次我没啥废话了... --------------笔记开始--------------- 投影矩阵与消灭矩阵 首先是上次没证的若干OLS性质。基本都是公式。我就照...
  • xiebaochun
  • xiebaochun
  • 2014年10月31日 16:48
  • 2029

【Unity Shader入门精要】— Unity Shader基础

内容会持续更新,有错误的地方欢迎指正,谢谢!引言Unity Shader是Unity为开发者提供的高层级的渲染抽象层,它让开发者更加轻松地管理着色器代码以及渲染设置(如开启/关闭混合、深度测试、设置渲...
  • BillCYJ
  • BillCYJ
  • 2017年10月18日 14:05
  • 119

UNITY SHADER入门精要_学习笔记1

1.注意OpenGL和DirectX的坐标轴: 2.部分专业名词介绍 #pragma surface surfaceFunction lightModel[opti...
  • xj1009420846
  • xj1009420846
  • 2017年04月07日 10:35
  • 502

JavaScript面向对象精要(二)

四、构造函数和原型对象1. 构造函数构造函数就是用new创建对象时调用的函数。使用构造函数的好处在于所有用同一个构造函数创建的对象都具有同样的属性和方法。function Person(){} var...
  • ligang2585116
  • ligang2585116
  • 2017年01月08日 19:02
  • 2463
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:sizeof 精要
举报原因:
原因补充:

(最多只允许输入30个字)