本文记录了有关sizeof的一些计算,主要有下面的四种情况:(如有错误,敬请留言)

  1. 使用sizeof()计算普通变量所占用的内存空间
  2. sizeof计算类对象所占用空间的大小-用到了字节对齐
  3. sixeof计算含有虚函数的类对象的空间大小
  4. sizeof计算虚拟继承的类对象的空间大小

使用sizeof()计算普通变量所占用的内存空间

#include <iostream>
#include <stdlib.h>
using namespace std;//如果数组变量被传入函数中做sizeof()运算,则和指针的运算没有区别。
void Func( char str[100] )
{cout<<"Fun: == "<<sizeof(str)<<endl;//4字节的指针
}int main()
{char str[] = "Hello";char *p = str;int n = 10;cout<<"str == "<<sizeof(str)<<endl;//结果=6=strlen("Hello")+1;数值中要留一个元素保存字符串结束符
    Func(str);//2个结果都是4,win32下,指针和int都是4字节cout << "p ==" << sizeof(p) << endl;cout << "n ==" << sizeof(n) << endl;//结果4void *q = malloc(100);//100字节的堆内存cout << "void * == " << sizeof(q) << endl;//还是4(指针类型的大小)char *ch = (char *)malloc(sizeof(char)*10);cout << "char * == " <<sizeof(ch) << endl;//还是4(指针类型的大小)return 0;
}
//数组和指针的sizeof()是有区别的。
//对于指针,不论何种类型,其大小都是4字节的。

通过上面的示例,我们可以看到:sizeof计算的都是数据类型占用空间的大小,除了一种情况,就是初始化char str[]="Hello"的时候,sizeof计算的是字符串的长度+1.


sizeof计算类对象所占用空间的大小-用到了字节对齐

#include <iostream>
using namespace std;class A
{
public:int i;//4
};
class AA
{
public:double d;int i;//8+4+4(补全)
};
class B
{
public:char ch;//1
};
class C
{
public:int i;short j;//4+2+2(补全)
};
class D
{
public:int i;short j;char ch;//4+2+1+1(补全)
};
class E
{
public:int i;int ii;short l;char ch;char chr;//4+4+2+1+1
};
class F
{
public:int i;int ii;int iii;short j;char ch;char chr;//4+4+4+2+1+1
};
class FF
{
public:short j;int i;char ch;int ii;char chr;int iii;//2+2(补全)+4+1+3(补全)+4+1+3(补全)+4=24
};
int main()
{cout<<"sizeof(double) == "<<sizeof(double)<<endl;//4字节cout<<"sizeof(float) == "<<sizeof(float)<<endl;//4字节cout<<"sizeof(int) == "<<sizeof(int)<<endl;//4字节cout<<"sizeof(short) == "<<sizeof(short)<<endl;//2cout<<"sizeof(char) == "<<sizeof(char)<<endl<<endl;//1
cout<<"sizeof(A) == "<<sizeof(A)<<endl;cout<<"sizeof(AA) == "<<sizeof(AA)<<endl;//最宽的类型是8字节的。cout<<"sizeof(B) == "<<sizeof(B)<<endl;cout<<"sizeof(C) == "<<sizeof(C)<<endl;cout<<"sizeof(D) == "<<sizeof(D)<<endl;cout<<"sizeof(E) == "<<sizeof(E)<<endl;cout<<"sizeof(F) == "<<sizeof(F)<<endl;cout<<"sizeof(FF) == "<<sizeof(FF)<<endl;//同样的类型个数,只是顺序变了,就不一样了。return 0;
}

  1. 字节对齐的准则
  2. 结构体的首地址能够被其最宽基本类型成员的大小所整除。
  3. 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍(编译器会在成员之间加上填充字节)如FF
  4. 结构体的总大小为结构体中最宽基本类型成员大小的整数倍(编译器会在最后成员的后面填充字节)如AA

sixeof计算含有虚函数的类对象的空间大小

#include <iostream>
using namespace std;
class Base
{
public:Base(int x):a(x){}void print(){cout<<"base"<<endl;}
private:int a;
};
class Dervied:public Base
{
public:Dervied(int x):Base(x-1),b(x){}void print(){cout<<"Dervied"<<endl;}
private:int b;
};
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;
};int main()
{Base obj1(1);cout<<"size of base obj1 is "<<sizeof(obj1)<<endl;Dervied obj2(2);cout<<"size of Dervied obj2 is "<<sizeof(obj2)<<endl;A a(1);cout<<"size of A obj is "<<sizeof(a)<<endl;B b(2);cout<<"size of B obj is "<<sizeof(b)<<endl;return 0;
}

  1. Base类:占用内存大小是sizeof(int),print()不占用内存空间。4
  2. Dervied类:比Base类多了一个整形成员,因而多4个字节。8
  3. A类:因为含有虚函数,因此占用内存除了一个整型变量之外,还包括一个隐含的虚表指针成员,一共8字节
  4. B类:比A类多了一个整型成员。所以12字节。

普通函数不占用内存,只要有虚函数,就会占用一个指针大小的内存,原因,系统多用了一个指针维护这个类的虚函数表, 并注意到,这个虚函数无论含有多少项(类中含有多少个虚函数)都不会再影响类的大小了。


sizeof计算虚拟继承的类对象的空间大小

#include <iostream>
using namespace std;
class A{};
class B{};
class C:public A,public B{};
class D:virtual public A{};
class E:virtual public A,virtual public B{};
class F
{
public:int a;static int b;
};
int F::b = 10;
int main()
{cout<<"sizeof(A) =="<<sizeof(A)<<endl;cout<<"sizeof(B) =="<<sizeof(B)<<endl;cout<<"sizeof(C) =="<<sizeof(C)<<endl;cout<<"sizeof(D) =="<<sizeof(D)<<endl;cout<<"sizeof(E) =="<<sizeof(E)<<endl;cout<<"sizeof(F) =="<<sizeof(F)<<endl;return 0;
}

  1. A类为空,编译器会安排一个char类型给他,用来标记每一个对象。1字节
  2. C类,多重继承,依然1字节
  3. D类,虚拟继承A,编译器会安排一个指向父类的指针,为4.因为有了指针,所以不会安排char类型了。
  4. E类,虚拟继承多个,但是只要一个指针就可以了。
  5. F类,静态成员的空间不在类的实例中,而是像全局变量一样,在静态存储区,被每一个类的实例共享。

转载于:https://www.cnblogs.com/zi-xing/p/4593835.html

Sizeof的计算看内存分配相关推荐

  1. C语言-动态内存分配总结

    目录 1 malloc 2 calloc 区别联系 3 memset 4 realloc 1 malloc void *malloc( unsigned int num_bytes) 分配长度为num ...

  2. 在malloc函数中为什么常用sizeof来设定内存分配的大小?

    在malloc函数中为什么常用sizeof来设定内存分配的大小? 例子:为40个整数变量分配内存并赋值,然后系统在收回这些内存. #include<stdlib.h> #include&l ...

  3. 从一个微型例子看“C/C++的内存分配机制”和“数组变量名与指针变量名”

    内存分配方式有三种: 从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. 在栈上创建. 在执行函数时,函数内局部变量的存储单元都 ...

  4. 7种垃圾收集器与内存分配策略,看这一篇就够了

    垃圾收集器与内存分配策略-垃圾收集器 (A).图中展示了7种不同分代的收集器: Serial.ParNew.Parallel Scavenge.Serial Old.Parallel Old.CMS. ...

  5. 02.1跟雨痕看go源码-内存分配(分配回收)

    内存分配和垃圾回收有关,这里我们可以先看一下内存分配. 垃圾回收比较复杂,后面讲. 一开始雨痕大大说了几个基本策略: 每次从操作系统申请一大块内存(比如1MB),以减少系统调用. 将申请到的大块内存按 ...

  6. 【计算机操作系统】测试题:动态分区内存分配;调页系统;分页存储管理;快表是什么?计算指令操作数地址;有效存储访问时间,缺页次数,缺页率;

    目录 填空题: 选择题: 简答题: 应用题: 填空题: 1. 在动态分区式内存分配算法中,倾向于优先使用低地址部分空闲区的算法是   首次适应算法   :能使内存空间中空闲区分布较均匀的算法是  循环 ...

  7. Eigen向量化内存对齐/Eigen的SSE兼容,内存分配/EIGEN_MAKE_ALIGNED_OPERATOR_NEW

    1.总结 对于基本数据类型和自定义类型,我们需要用预编译指令来保证栈内存的对齐,用重写operator new的方式保证堆内存对齐.对于嵌套的自定义类型,申请栈内存时会自动保证其内部数据类型的对齐,而 ...

  8. 4 OC 中的内存分配以及内存对齐

    目录 一  OC  中的内存分配 一  OC  中的内存分配 student 结构体明明是20?为什么是24个字节,因为结构体会按照本身成员变量最大的内存进行对齐,最大成员变量是8个字节,因此就是8的 ...

  9. 动态内存分配与柔性数组

    什么时动态内存分配 一般我们写程序都是在栈区分配空间,如果我们想根据需求想随时存放随时释放数据,堆区可以实现根据需求想系统申请所需大小的空间. 建立内存的动态分配 内存的动态分配是通过系统提供的函数来 ...

最新文章

  1. 用jsp实现右导航窗格_不想升级操作系统,可以用这三种方法阻止Windows10更新
  2. python语言程序设计2019版第二章课后答案-python语言程序设计基础课后答案第二章...
  3. 视频开发(即时通讯平台)
  4. Java 配置maven及阿里云镜像
  5. java解压服务器文件夹,java获取远程服务器上的文件夹
  6. 开放防火墙/26ip段_在5个不同国家/地区采用开放硬件设计的电子产品
  7. oracle10gr2安装教程,Solaris10安装Oracle10gR2时的注意事项
  8. 【读书笔记】 多线程程序常见bug
  9. 2014小米校园招聘笔试(10.13北京)
  10. python绘图颜色代码_Python绘图的颜色设置
  11. Vs2010中文版MSDN 安装方法
  12. 安装UWB定位系统设备需要注意什么?
  13. 美国服务器用于外贸建站有哪些好处
  14. TestFlight测试步骤
  15. 一百块组装可玩LOL的电脑
  16. 测试设计之状态转换图
  17. U盘中毒,文件夹或文件打不开的解决方法--实用
  18. Sophos XG Firewall:如何使用Windows Server 2012为企业无线身份验证配置RADIUS
  19. AI成为硬件增效“杀手锏”,百度输入法的「To B」探索
  20. 春晚 “北帝” “东邪”

热门文章

  1. SoX-linux里操作音频的瑞士×××
  2. WaterfallTree(瀑布树) 详细技术分析系列
  3. ASP.NET 数据访问类
  4. python socket 实现的简单http服务器
  5. 蓝桥杯 ADV-78 算法提高 最长单词
  6. 1029. 旧键盘(20)-PAT乙级真题
  7. 蓝桥杯 ADV-94算法提高 复数归一化
  8. 如何禁用和启用mysql外键约束
  9. 不同微服务独立数据库,如何保障微服务架构下的数据一致性
  10. bat命令运行java程序