C++类所占内存大小计算

转载时请注明出处和作者联系方式
文章出处:http://blog.csdn.net/chenchong08
作者联系方式:vision_chen@yeah.net

说明:笔者的操作系统是32位的。

class A {};
sizeof( A ) = ?
sizeof( A ) = 1
明明是空类,为什么编译器说它是1呢?
空类同样可以实例化,每个实例在内存中都有一个独一无二的地址,为了达到这个目的,编译器往往会给一个空类隐含的加一个字节,这样空类在实例化后在内存得到了独一无二的地址.所以sizeof( A )的大小为1.

class B
{
public:
  B() {}
  ~B() {}
  void MemberFuncTest( int para ) { }
  static void StaticMemFuncTest( int para ){  }
};
sizeof( B ) = ?
sizeof( B ) = 1
类的非虚成员函数是不计算在内的,不管它是否静态。

ps:成员函数还是以一般的函数一样的存在。a.fun()是通过fun(a.this)来调用的所谓成员函数只是在名义上是类里的。其实成员函数的大小不在类的对象里面,类所占内存的大小不包括成员函数的大小,虚拟成员函数除外。同一个类的多个对象共享函数代码。而我们访问类的成员函数是通过类里面的一个指针实现,而这个指针指向的是一个table,table里面记录的各个成员函数的地址(当然不同的编译可能略有不同的实现)。所以我们访问成员函数是间接获得地址的。所以这样也就增加了一定的时间开销,这也就是为什么我们提倡把一些简短的,调用频率高的函数声明为inline形式(内联函数)。

class C
{
 C(){}
 virtual ~C() {}
};
sizeof( B ) = ?
sizeof( B ) = 4
类D有一个虚函数,存在虚函数的类都有一个一维的虚函数表叫虚表,虚表里存放的就是虚函数的地址了,因此,虚表是属于类的。这样的类对象的前四个字节是一个指向虚表的指针,类内部必须得保存这个虚表的起始指针。在32位的系统分配给虚表指针的大小为4个字节,所以最后得到类C的大小为4.

class D
{
 D(){}
 virtual ~D() {}
 virtual int VirtualMemFuncTest1()=0;
 virtual int VirtualMemFuncTest2()=0;
 virtual int VirtualMemFuncTest3()=0;
};
sizeof( D ) = ?
sizeof( D ) = 4
原理同类C,不管类里面有多少个虚函数,类内部只要保存虚表的起始地址即可,虚函数地址都可以通过偏移等算法获得。

class E
{
 int  m_Int;
 char m_Char;
};
sizeof( E ) = ?
sizeof( E ) = 8
32位的操作系统int占4个字节,char占一个字节,加上内存对齐的3字节,为8字节。

class F : public E
{
 static int s_data ;
};
int F::s_data=100;
sizeof( F ) = ?
sizeof( F ) = 8
类F为什么跟类E一样大呢?类F的静态数据成员被编译器放在程序的一个global data members中,它是类的一个数据成员,但是它不影响类的大小,不管这个类实际产生了多少实例还是派生了多少新的类,静态成员数据在类中永远只有一个实体存在,而类的非静态数据成员只有被实例化的时候,他们才存在.但是类的静态数据成员一旦被声明,无论类是否被实例化,它都已存在.可以这么说,类的静态数据成员是一种特殊的全局变量.

class G : public E
{
 virtual int VirtualMemFuncTest1(int para)=0;
 int m_Int;
};
class H : public G
{
 int m_Int;
};
sizeof( G ) = ?
sizeof( H ) = ?
sizeof( G ) = 16
sizeof( H ) = 20
可以看出子类的大小是本身成员的大小再加上父类成员的大小.如果父类还有父类,也加上父类的父类,这样一直递归下去。

class I : public D
{
 virtual int VirtualMemFuncTest1()=0;
 virtual int VirtualMemFuncTest2()=0;
};
sizeof( I ) = ?
sizeof( I ) = 4
父类子类工享一个虚函数指针,虚函数指针保留一个即可。

总结:
空的类也是会占用内存空间的,而且大小是1,原因是C++要求每个实例在内存中都有独一无二的地址。
(一)类内部的成员变量:
普通的变量:是要占用内存的,但是要注意内存对齐(这点和struct类型很相似)。
static修饰的静态变量:不占用内存,原因是编译器将其放在全局变量区。
从父类继承的变量:计算进子类中
(二)类内部的成员函数:
非虚函数(构造函数、静态函数、成员函数等):不占用内存。
虚函数:要占用4个字节(32位的操作系统),用来指定虚拟函数表的入口地址。跟虚函数的个数没有关系。父类子类工享一个虚函数指针。

构成对象本身的只有数据,任何成员函数都不隶属于任何一个对象,非静态成员函数与对象的关系就是绑定,绑定的中介就是this指针。成员函数为该类所有对象共享,不仅是处于简化语言实现、节省存储的目的,而且是为了使同类对象有一致的行为。同类对象的行为虽然一致,但是操作不同的数据成员。

测试代码如下:

[cpp] view plaincopyprint?
  1. <SPAN style="FONT-SIZE: 18px">/*
  2. * file name   : main.cpp
  3. * description : test the size of c++'s class
  4. * create on   : 2012-05-31
  5. * create by   : chenchong
  6. * email         : vision_chen@yeah.net
  7. */
  8. #include<iostream>
  9. using namespace std;
  10. class A {};
  11. class B
  12. {
  13. public:
  14. B() {}
  15. ~B() {}
  16. void MemberFuncTest( int para ) { }
  17. static void StaticMemFuncTest( int para ){  }
  18. };
  19. class C
  20. {
  21. C(){}
  22. virtual ~C() {}
  23. };
  24. class D
  25. {
  26. D(){}
  27. virtual ~D() {}
  28. virtual int VirtualMemFuncTest1()=0;
  29. virtual int VirtualMemFuncTest2()=0;
  30. virtual int VirtualMemFuncTest3()=0;
  31. };
  32. class E
  33. {
  34. int  m_Int;
  35. char m_Char;
  36. };
  37. class F : public E
  38. {
  39. static int s_data ;
  40. };
  41. int F::s_data=100;
  42. class G : public E
  43. {
  44. virtual int VirtualMemFuncTest1(int para)=0;
  45. int m_Int;
  46. };
  47. class H : public G
  48. {
  49. int m_Int;
  50. };
  51. class I : public D
  52. {
  53. virtual int VirtualMemFuncTest1()=0;
  54. virtual int VirtualMemFuncTest2()=0;
  55. };
  56. int main( int argc, char **argv )
  57. {
  58. cout<<"sizeof( A ) = "<<sizeof( A )<<endl;
  59. cout<<"sizeof( B ) = "<<sizeof( B )<<endl;
  60. cout<<"sizeof( C ) = "<<sizeof( C )<<endl;
  61. cout<<"sizeof( D ) = "<<sizeof( D )<<endl;
  62. cout<<"sizeof( E ) = "<<sizeof( E )<<endl;
  63. cout<<"sizeof( F ) = "<<sizeof( F )<<endl;
  64. cout<<"sizeof( G ) = "<<sizeof( G )<<endl;
  65. cout<<"sizeof( H ) = "<<sizeof( H )<<endl;
  66. cout<<"sizeof( I ) = "<<sizeof( I )<<endl;
  67. #if defined( _WIN32 )
  68. system("pause");
  69. #endif
  70. return 0;
  71. }
  72. </SPAN>
/** file name   : main.cpp* description : test the size of c++'s class* create on   : 2012-05-31* create by   : chenchong* email         : vision_chen@yeah.net*/#include<iostream>using namespace std;class A {}; class B
{
public:B() {}~B() {}void MemberFuncTest( int para ) { }static void StaticMemFuncTest( int para ){  }
};class C
{C(){}virtual ~C() {}
};class D
{D(){}virtual ~D() {}virtual int VirtualMemFuncTest1()=0;virtual int VirtualMemFuncTest2()=0;virtual int VirtualMemFuncTest3()=0;
};class E
{int  m_Int;char m_Char;
};class F : public E
{static int s_data ;
};
int F::s_data=100;class G : public E
{virtual int VirtualMemFuncTest1(int para)=0;int m_Int;
};
class H : public G
{int m_Int;
};class I : public D
{virtual int VirtualMemFuncTest1()=0;virtual int VirtualMemFuncTest2()=0;
};int main( int argc, char **argv )
{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;cout<<"sizeof( G ) = "<<sizeof( G )<<endl;cout<<"sizeof( H ) = "<<sizeof( H )<<endl;cout<<"sizeof( I ) = "<<sizeof( I )<<endl;#if defined( _WIN32 )system("pause");
#endifreturn 0;
}

Windows 7 32位 VC 2010运行结果:

Linux(cent os 6.2 32位)运行结果:

转载于:https://www.cnblogs.com/wonderKK/archive/2012/11/19/2776659.html

(转)C++类所占内存大小计算相关推荐

  1. 利用bitmap处理海量数据问题:43亿QQ号所占内存大小为什么是512M?40亿个QQ号如何去重?

    ​参考: 腾讯43亿QQ号码用完后怎么办? 腾讯三面:40亿个QQ号码如何去重 一.背景: 首先,明确两点: QQ号是 unsigned int 类型(4字节无符号整数,共32bit), 也就是说 Q ...

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

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

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

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

  4. C++中的类所占内存空间总结

    C++中的类所占内存空间总结 最近在复习c++的一些基础,感觉这篇文章很不错,转载来,大家看看! 类所占内存的大小是由成员变量(静态变量除外)决定的,成员函数(这是笼统的说,后面会细说)是不计算在内的 ...

  5. 初识C语言(一)常见变量的含义、所能存储数据的范围、及其所占内存大小。

    一 .变量的类型及其所占内存大小 刚开始学习C语言的时候就会接触到变量的这个概念,变量有很多种类,整型,浮点型等.那么就要了解一下每种类型的变量的含义.能够存储的数据的范围.以及它所占内存的大小. 提 ...

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

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

  7. 共用体和结构体所占内存大小的计算方法

    共同体作用:让几个不同类型的变量共享同一个内存地址. 共用体所占内存大小:共用体所占内存的大小即公用体中长度最大元素所占用的字节数. #include<stdio.h> typedef u ...

  8. BERT所占内存的计算

    @苹果树数据科技有限公司-AI部 BERT所占内存的计算 以BERT-base为例,占用110million的参数,数据格式为半精度浮点型(FP16),则占用内存的计算如下: 1B=8字节 FP16表 ...

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

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

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

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

最新文章

  1. Camel之AsyncProcessor
  2. OpenSUSE 11 安装Qt5.0,失败,失败,失败,留个坑,以后来填,万一实现了呢
  3. 题目1254:N皇后问题(DFS)
  4. 用package.json配置NodeJS项目的模块声明
  5. Anaconda装OpenCV
  6. python算法与数据结构-快速排序算法(36)
  7. matlab实现单纯型法解线性规划_【考研运筹学讲解】线性规划(一)
  8. linux在双系统中消失了,双系统重新安装windows后,ubuntu选项消失
  9. 【ArcGIS遇上Python】ArcGIS Python批处理入门到精通实用教程目录
  10. php生成10万个字符串,有什么好的方法可以生成十万条不重复的13位纯数字字符串...
  11. python 生成器函数_Python 生成器函数
  12. 知识技能归档--CA-PKI体系-20210324
  13. HashMap源码分析-jdk1.6和jdk1.8的区别
  14. Ergo生态:首个算法稳定币SigmaUSD正式启动
  15. 数据结构上机实践第14周项目2 - 二叉树排序树中查找的路径
  16. 计算机硬盘扇区修复,如何修复硬盘启动扇区
  17. python图像二值化处理_python实现opencv图像二值化
  18. python控制蓝牙pybluez_Python之蓝牙通讯模块pybluez学习笔记
  19. 致我爱的动漫--Fate 系列 Part 1:《Fate/Zero》
  20. 【EtherCAT分析】三、EtherCAT从站设备描述文件设计

热门文章

  1. 基于论辩图谱的互动论点对识别
  2. 深度学习文本分类|模型代码技巧
  3. 从 0 开始机器学习 - 机器学习系统的设计与误差分析
  4. 【NER】NLP-入门实体命名识别(NER)+Bilstm-CRF模型原理Pytorch代码详解——最全攻略...
  5. 《神经网络与深度学习》课程笔记(4)-- 浅层神经网络
  6. pandas—pd.DataFrame.sample
  7. 算法与数据中台:网约车业务实践
  8. 解析内、外职业发展规划秘诀
  9. 「三分钟系列05」3分钟看懂并发与并行
  10. PyTorch:tensor-基本操作