以下均是在VS2017下的结果

结构体内存大小的计算:

用例一:

#include<stdio.h>
union ss
{int a;char b;
};
struct MyStruct
{int temp1;//4个字节char  temp2;//一个字节,补齐3个字节ss aa;//4个字节char temp3;//一个字节char temp4;//一个字节,补齐两个字节
};
int main()
{printf("%d", sizeof(MyStruct));return 0;
}

  输出 16

解析:对齐规则是按照成员的声明顺序,依次安排内存,对齐字节数为最大成员变量的字节大小,偏移量为最大成员变量的字节数的整数倍,在这个程序中对齐字节数为4,计算步骤如下:

首先是temp1 四个字节,temp2 一个字节,还剩3个字节,因为后面是aa 4个字节,可以自己对齐,所以temp2需要补齐3个字节, temp3 一个字节,temp4一个字节,对齐是4个字节,还剩2个字节需要补齐。所以总共是16个字节。

#include<stdio.h>
union ss
{int a;double b;
};
struct MyStruct
{int temp1;//4个字节char  temp2;//1个字节,对齐是8个字节,还需3个字节补齐ss aa;//8个字节char temp3;//1个字节short temp4;//2个字节,补齐还需要5个字节
};
int main()
{printf("%d", sizeof(MyStruct));return 0;
}

  输出结果为 24

#include<stdio.h>
union ss
{int a;double b;
};struct student
{int name;char sex;double num;};
struct MyStruct
{int temp1;//4个字节char  temp2;//1一个字节,补齐3个字节ss aa;//8个字节char temp3;//一个字节short temp4;//2个字节,补齐5个字节student people;//16个字节
};
int main()
{printf("%d", sizeof(MyStruct));return 0;
}

  结果为 40

解析:此时需要注意的是,对齐字节数8个字节,而不是16个字节。student people 对象内部先进行一次对齐,然后如果如果是外面对齐字节数的整数倍就不需要

再进行对齐了,如果不是就需要再次进行对齐。

下面的是需要二次对齐的程序:

#include<stdio.h>
struct MyStruct
{char temp1;char temp2;
};
struct student
{int name;//4个字节char sex;//1个字节MyStruct aa;//2个字节char temp;//1个字节};
int main()
{printf("%d", sizeof(student));}

  输出为 8

#include<stdio.h>
union ss
{int a;double b;
};struct student
{//int name;//char sex;int num;};
struct MyStruct
{int temp1;//4个字节char  temp2;//1一个字节,补齐3个字节ss aa;//8个字节char temp3;//1个字节short temp4;//2个字节student people;//4个字节,补齐一个字节
};
int main()
{printf("%d", sizeof(MyStruct));return 0;
}

  输出结果为:24

总结,在一个结构体中有另一个结构体的对象时,对齐字节数与这个结构体对象的字节数无关,只与结构体中的成员变量和union 有关。

类的内存大小的计算

只含有成员函数的类和空类的内存大小:

#include<iostream>
using namespace std;
class student
{
public:student() {cout << "构造函数" << endl;}//void fun();
};
int main()
{cout << sizeof(student) << endl;return 0;
}

  运行结果: 1

解析:如果是空类也会输出1。如果一个类只含有成员函数没有成员变量或者虚函数,类的大小都是1。如果含有静态成员变量或者是静态成员函数,也会是1,因为静态成员变量和静态成员函数是类的所有对象共享的,它并不存放在一个实例化对象中

为什么空类也会是1呢?

所谓类的实例化就是在内存中分配一块地址,每一个实例在内存中都有独一无二的地址,而了到达这个效果,编译器往往会给一个空类隐含的增加一个字节,这样实例化出来的每一个空类的对象都会得到一个独一无二的地址。如果空类的大小是0的话,那么实例化出来的所有空类对象都是在同样一个内存地址上,就相当于同一个对象,这不是我们想要的。

只含有静态成员函数和静态成员变量的类的内存大小:

#include<iostream>
using namespace std;
class student
{static int b;static void func();
};
int main()
{cout << sizeof(student) << endl;return 0;
}

  输出结果:1

解析:因为静态成员变量和静态成员函数都是类的所有对象共享的,静态成员变量存放在全局存储区,静态成员变量和静态成员函数在编译时就已经在全局区分配的内存。

含有成员变量的类的内存大小:

#include<iostream>
using namespace std;
class student
{int a;//4个字节char c;//1个字节,对齐,需要补齐3个字节static int b;static void func();
};
int main()
{cout << sizeof(student) << endl;return 0;
}

  输出为 8

含有虚函数的类的内存大小:

#include<iostream>
using namespace std;
class student
{int a;//4个字节char c;//1一个字节,对齐,补齐3个字节static int b;
public:static void func();virtual void fly();//4个字节
};
int main()
{cout << sizeof(student) << endl;return 0;
}

  

  输出为 12

解析:虚函数会产生一个虚函数指针,指针大小为4个字节,虚函数指针指向虚函数表。

但是并不是每一个虚函数都会产生一个虚函数指针,同一个类中的所有虚函数只会产生一个虚函数指针。

继承下的类的内存大小:

#include<iostream>
using namespace std;
class student
{int a;char c;static int b;
public:static void func();virtual void fly();
};
class student1: public student
{int d;//4个字节
};
int main()
{cout << sizeof(student1) << endl;return 0;
}

  输出 16

解析:派生类会继承父类的成员变量和虚函数等,所以子类的内存大小是在父类的内存大小的基础上加上自己增加的内存大小。

父类和子类中都有虚函数的类的内存大小:

#include<iostream>
using namespace std;
class student
{int a;char c;static int b;
public:static void func();virtual void fly();
};
class student1: public student
{int d;
public:void fly();virtual void eat();
};
int main()
{cout << sizeof(student1) << endl;return 0;
}

  输出为:16

问题:子类声明了一个虚函数且该虚函数是父类中没有的虚函数为什么子类没有新产生一个虚函数指针。

这个涉及到内存布局问题,首先是基类产生了一个虚函数指针,这个虚函数指针会指向虚函数表,表中存放的是基类的虚函数。子类也会继承到这个虚函数指针,虚函数指针指向虚函数表,表中先是存放基类的虚函数,再存放子类的基函数,如果子类重载了父类的某些虚函数,那么新的虚函数将虚函数表中父类对应的虚函数覆盖

虚继承——空类

#include<iostream>
using namespace std;
class student
{};
class student1: virtual student
{};
int main()
{cout << sizeof(student1) << endl;return 0;
}

  输出结果为 4

虚继承——基类含有虚函数指针,子类不含有虚函数指针

#include<iostream>
using namespace std;
class student
{int a;char c;//static int b;
public://static void func();virtual void fly();
};
class student1: virtual student
{int d;
public:void fly();//virtual void eat();
};
int main()
{cout << sizeof(student1) << endl;return 0;

  此时输出为:20

解析:因为虚继承会再产生一个虚函数指针,去指向对应的基类,防止子类继承多个一样的基类,造成资源浪费

虚继承:子类和父类都有虚函数

#include<iostream>
using namespace std;
class student
{int a;char c;//static int b;
public://static void func();virtual void fly();
};
class student1: virtual student
{int d;
public:void fly();virtual void eat();
};
int main()
{cout << sizeof(student1) << endl;return 0;
}

  输出:24

解析:此时是子类声明的虚函数是父类没有的,则此时子类会再产生一个虚函数指针,如果此时子类的所有虚函数都是继承自基类的,则不会产生虚函数指针。

转载于:https://www.cnblogs.com/wuyepeng/p/9862144.html

struct和class内存大小的计算相关推荐

  1. 安卓图片内存优化(一)——图片占用内存大小的计算

    安卓开发中经常会遇到因为图片处理不当导致的oom问题,因为系统分配给每个应用的最大内存空间是有限的,正常只有几十上百兆(排除通过特殊手段获取到几百兆内存空间的情况).所以为了节省更多的空间需要对图片进 ...

  2. C++_类和结构体所占内存大小,静态成员问题

    C++_类和结构体所占内存大小,静态成员问题 静态成员未初始化或者未调用(当然静态成员必须类外初始化才能调用)是不占内存的.静态成员不占类或结构体的内存 静态成员函数同样只声明未定义同样不占内存 指针 ...

  3. C/C++计算类/结构体和联合体(union)所占内存大小(内存对齐问题)

    目录 一,内存对齐的三条规则 二,注意事项: 三,举例说明 1,示例1 2,示例2 3,示例3 4,示例4 四,联合体(union) 五,字节对齐的原因 六,计算练习 一,内存对齐的三条规则 数据成员 ...

  4. Java计算一个对象所占内存大小_Java程序计算各种对象所占内存的大小的方法

    System.out.println("--- Memory Usage:"); /*打印一行字符串---Memory Usage*/ Runtime rt=Runtime.get ...

  5. 【C 语言】二级指针作为输入 ( 二维数组 | 二维数组内存大小计算 | 指针跳转步长问题 )

    文章目录 一.二维数组内存大小计算 二.二维数组内存大小意义 一.二维数组内存大小计算 给定一个二维数组 : 该 二维数组 中有 444 个 一维数组 , 每个一维数组有 101010 个 char ...

  6. python获取对象的大小_Python实现计算对象的内存大小示例

    本文实例讲述了Python实现计算对象的内存大小.分享给大家供大家参考,具体如下: 一般的sys.getsizeof()显示不了复杂的字典. 查看类中的内容: def dump(obj): for a ...

  7. Java对象内存大小计算

    背景 今天办公室两个人事妹子因为一道Java试题各持己见,誓死捍卫自己的答案(对,是HR没错 -- 程序猿快没活路了). 题:字符串 "7天学会JAVA" 占用的内存空间是 ( ) ...

  8. DDR内存大小计算以及MIG核配置

    范围 本文适用于DDR内存大小计算以及MIG核配置. DDR内存大小计算 DDR型号 DDR型号为 MT41K256M16TW-107 图2.1.1 图2.1.2 此片DDR行地址位宽为[14:0], ...

  9. Java 中对象占用内存大小计算

    原文地址 mp.weixin.qq.com byte 与 bit bit:位,比特.信息的最小单位,二进制数中的一个位数 (二进制位),其值为"0" 或"1": ...

最新文章

  1. PHP内核中的哈希表结构
  2. hadoop定位文件读取
  3. springmvc + jquery 错误.ClassNotFoundException: org.apache.taglibs.standard.tlv.JstlCoreTLV
  4. 数组名加取地址符的理解
  5. Apache Camel教程– EIP,路由,组件,测试和其他概念的简介
  6. Musical Theme POJ - 1743(后缀数组+二分)
  7. GitHub 五万星登顶,程序员命令行最全技巧宝典!
  8. Golang 须知知识点
  9. matlab2c使用c++实现matlab函数系列教程-rand函数
  10. 【必修一】部分数学名词与数学符号
  11. 狡兔死,良弓藏-每个王朝都一样
  12. 抽象工厂模式简单实例
  13. “终端服务器超出了最大允许连接数”的解决方法汇总
  14. 【190320】VC++ 机器人语音控制系统源代码
  15. 工行纸黄金软件测试,只需一万元,工行刷星7级下卡2万的方法
  16. 【Linux c】sipc
  17. 《刻意练习:如何从新手到大师》安德斯著PDF下载
  18. js判断手机是否是苹果
  19. C++ 上溢和下溢(overflow underflow)
  20. android逆向分析腾讯微视研究无限循环视频嵌套滑动不中断的实现方式

热门文章

  1. python入门经典例题-Python入门经典练习题
  2. 我学会了python接下来学什么比较好-我,二本,学会Python后月入上万
  3. python制作工资计算器-Python制作个税计算器
  4. python和c哪个适合入门-编程入门选什么语言好?C 语言还是Python ?为你解析
  5. python常用内置模块-python常用的内置模块
  6. python 编程一日一练-Python每日一练0022
  7. python资料下载-python电子书学习资料打包分享百度云资源下载
  8. python爬虫赚钱的经历-十年真ㆍPython大佬用爬虫赚钱的自述!看完学到了!
  9. 学python要多少钱-python学习费用多少合适
  10. python恶搞小程序-有趣的python小程序