以Fruit和Apple为例进行分析:
Fruit和Apple的定义如下:
通过在两种编译环境下的测试(GNU GCC & VS2015),可以发现这两种编译器的对象模型是一样的,如下图所示:
Apple是Fruit的子类,此为两级的单链继承结构。在Apple和Fruit对象内部,均遵循以下原则:
- 对象中的第一个成员是指向虚表的虚指针;
- 对象是按照声明中的顺序被保存的;
然而,两种编译器的内存的位对齐方式略有不同。
对于GNU GCC编译器而言,其遵循以下的原则:
- 按声明中出现的顺序进行内存分配
- 变量的起始偏移地址必须是自己大小的倍数,例如在struct{bool a;double b;}中,a占1个字节,然而b的大小是8个字节,因此b必须从编译地址为8的位置看是,也就是说,a和b要空7个字节。其之所以这样设计,是因为在读取一个变量时,这种方式读取可以使cache速度更快。
- 如果类中存在虚函数,在对象的起始处会有虚指针。
- 在所有变量的内存分配结束后,对象要填补成内存中的最大的基本类型变量的倍数。例如,如果一个类中最大的基本类型是double,那么它最后需要填补成8的整数倍。
还有三个特点在Fruit和Apple的关系中没有涉及到,他们是:
- 多重继承的情况下,在每个基类的前边上会有不同的vptr;
- 如果在派生类中存在新的虚函数,则会产生一个兼容基类的虚表,而不会添加新的表;
- 组合关系时,内部类的起始地址应从内部类的最大的基本数据类型的整数倍处开始。
综合前4个特点,可以计算得到在GNU GCC的编译环境下,Fruit的大小是(4+4+8+(1+7))=24Bytes; Apple的大小是(24+4+(1+3))=32Bytes,如下图:
然而,在VS2015的编译环境下,虚指针位对齐的方式是不同的。VS2015中要求数据成员的起始地址也必须是内部最大基本数据类型的整数倍,也就是说,在虚指针和数据成员之间必须存在4个占位字节,因此Fruit的大小是((4+4)+(4+4)+8+(1+7))=32Bytes;而Apple的大小是(32+4+(1+4))=40;
如图所示,尽管指针变量的大小为4字节,no的偏移量仍然是从8开始的。
Apple的内存截图如下:
前32个字节:
后8个字节:
其中,0x649bfb00位虚指针地址,0xcc为占位符,第一个0xffffffff为no,0x0000000000000000为weight,0x01为key。
注:如果将double变量删去,则第一个数据成员从4开始,也就是说Fruit的大小应该变为(4+4+(1+3))=12,如图:
内存分配图如下:
这验证了VS2015编译器的额外条件。
C++对象模型与内存位对齐的简单分析(GNU GCC&VS2015编译器)的更多相关文章
-
20135337——Linux实践三:ELF文件格式(64位系统,简单分析)
ELF文件格式简单分析 (具体分析见上一篇ELF文件格式32位系统) ELF-header 第一行: 457f 464c :魔数: 0201 :64位系统,小端法 01 :文件头版本 剩余默认0: 第 ...
-
glibc内存泄露以及TCmalloc 简单分析
最近开发一个私人程序时碰到了严重的内存问题,具体表现为:进程占用的内存会随着访问高峰不断上升,直到发生OOM被kill为止.我们使用valgrind等工具进行检查发现程序并无内存泄露,经过仔细调查我们 ...
-
C语言精要总结-内存地址对齐与struct大小判断篇
在笔试时,经常会遇到结构体大小的问题,实际就是在考内存地址对齐.在实际开发中,如果一个结构体会在内存中高频地分配创建,那么掌握内存地址对齐规则,通过简单地自定义对齐方式,或者调整结构体成员的顺序,可以 ...
-
windows和Linux内存的对齐方式
一.内存对齐的初步解说 内存对齐能够用一句话来概括: "数据项仅仅能存储在地址是数据项大小的整数倍的内存位置上" 比如int类型占用4个字节,地址仅仅能在0,4,8等位置上. 例1 ...
-
c语言,内存字节对齐
引用:内存字节对齐 写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这是怎么回事呢?讲讲字节对齐吧. /************* ...
-
FFmpeg源代码简单分析:内存的分配和释放(av_malloc()、av_free()等)
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
-
C++:struct和union 内存字节对齐问题
转自:http://blog.csdn.net/wangyanguiyiyang/article/details/53312049 struct内存对齐问题 1:数据成员对齐规则:结构(struct) ...
-
C语言中的按位移动及其简单引用
C语言中的按位移动及其简单应用 在C语言中按位左移用”<<”表示,按位右移用”>>”表示. 按位左移和按位右移运算经常被用来替换乘二和除二运算,但是要注意,这两者之间并不完全等 ...
-
malloc分配内存进行对齐的操作
昨天面试高通Linux Kernel,面试官考了一个malloc内存对齐的问题,我晚上的时候细细的想了一下,实在是学习的不到位. 有的时候真的应该感谢,像是Qt.Ubuntu Gcc的编译器,他们做的 ...
随机推荐
-
C#程序设计---->;计算圆面积windows程序
值得说的就是添加一个回车事件, http://blog.csdn.net/nanwang314/article/details/6176604 private void textBox1_KeyDow ...
-
Bzoj 1042: [HAOI2008]硬币购物 容斥原理,动态规划,背包dp
1042: [HAOI2008]硬币购物 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1747 Solved: 1015[Submit][Stat ...
-
windows下apache+php+mysql配置
Apache 2.4.10(文件:httpd-2.4.10-win64-VC11.zip) php 5.6.26 (文件:php-5.6.25-Win32-VC11-x64.zip) mysql 5. ...
-
C# 根据IP查询地址归属地
必备文件:IPLocation.dll.QQWry.Dat 下载地址:http://pan.baidu.com/s/1jG1dlOy (可百度下载) 之前有过将 QQWry.Dat 转为 Access ...
-
3种SQL语句分页写法
在开发中经常会使用到数据分页查询,一般的分页可以直接用SQL语句分页,当然也可以把分页写在存储过程里,下面是三种比较常用的SQL语句分页方法,下面以每页5条数据,查询第3页为例子: 第一种:使用not ...
-
TP-Link WR842N VPN错误619 不能建立到远程计算机的连接
一直在用Tenacy这个VPN,不限时间不限流量的,可是近期发现链接VPN总是失败.在网上查了一下,发现居然是路由器的问题!回忆一下果然是路由器出事儿了,换这个842N之前,一直是能够链接VPN的,所 ...
-
介绍Python程序员常用的IDE和其它开发工具
概述 “工欲善其事,必先利其器”,如果说编程是程序员的手艺,那么IDE就是程序员的吃饭家伙了. IDE 的全称是Integration Development Environment(集成开发环境), ...
-
docker rancher 体验 (未完待续.....)
docker rancher 体验 官方 githubhttps://github.com/rancher/rancher 环境说明: 10.6.0.14010.6.0.18710.6.0.188 修 ...
-
numpy数组、向量、矩阵运算
可以来我的Github看原文,欢迎交流. https://github.com/AsuraDong/Blog/blob/master/Articles/%E6%9C%BA%E5%99%A8%E5%AD ...
-
Spring Boot——Linux 启动方式
1.前台启动:(ctrl+c会关闭程序) java -jar ****.jar 2.后台启动:(& 后台启动) java -jar ****.jar & 3.控制台输出启动 ...