美文网首页
c++内存对齐--GeekBand

c++内存对齐--GeekBand

作者: 数据小冰 | 来源:发表于2016-06-06 09:12 被阅读106次

c++中每个class包含两部分:数据和函数。对每个对象来说函数部分大家公用一份,而数据部分每个对象是独立的。所以在求一个class所占的空间大小的时候,求得数据部分所占的内存大小即为class的大小。下面小将结合实验的方式测试验证,考虑到vs下编译器和gcc的不同,小编这里分别独立验证,vs编译器验证采用vs2013IDE,gcc下的验证用codeblocks,测试都是在32系统下。class Fruit{
int no;
double weight;
char key;public:
void print() { }
virtual void process(){ }
};
所以这里的Fruit类,no是int型,占4个字节(实验是在32系统下,下面也是),weight是double型占8个字节,key是字符型占1个字节,别忘了这里有个虚函数,有一个隐藏的虚函数指针占4个字节。所以4+8+1+4=17个字节。
真是这么多吗,用sizeof测试下就知道了,在vs2013下sizeof(Fruit)==32.具体是怎么分配的呢?实验验证如下:

1.png

可以看到,指向虚函数的指针所占位置是从偏移量0位置开始的,占用8个字节。no变量从偏移量8位置开始,占用4个字节,但为了对齐,这里又分配了4个字节(alignment member)(size=4)。weight从偏移量16开始,占用8个字节。key从偏移量24开始,占用一个字节,但这里为了对齐,又分配了7个字节。所以共占用8+4+4(对齐)+8+1+7(对齐)=32字节。

vs2013下Fruit类和Apple类占用内存大小
有继承的情况占用的内存情况又是什么样的呢?比如下面的代码,Apple所占用的空间是多少呢?
class Apple : public Fruit{
int size;
char type;
public:
void save() { }
virtual void process(){ }
};
vs2013下实际测试sizeof(Apple)==40,具体是怎么分配的,验证结果如下

2.png

可以看到,Apple继承了Fruit数据,Furit部分所占用的空间是32字节,Apple类本身的size占4个字节,type 是占1个字节,但为了对齐多占了3个字节。

codeblocks(gcc)下Fruit类和Apple所占内存大小
同样是上面的Furit类和Apple,通过下面的代码测试

int main()
{
cout<<sizeof(Fruit)<<endl;
cout<<sizeof(Apple)<<endl;
return 0;
}
测试结果为:

codeblocks内存.png

哪在gcc下为什么Fruit类为什么是24字节呢?
虚函数指针(4字节)+no(4字节)+weight(8字节)+key(1字节,为了对齐添加了7字节)=24字节
哪gcc下Apple类是32字节是怎么来的呢?
虚函数指针(4字节)+no(4字节)+weight(8字节)+key(1字节,为了对齐添加了3字节)+size(4字节)+type(1字节,为了对齐添加了7字节)=32字节

为什么vs2013下和codeblocks下Fruit类和Apple类所占用的空间不同呢?
这是因为vs2013是微软的vc编译器,codeblocks是gcc编译器。两者在对齐的时候采用的策略不同。vs2013下采用的是以最大变量所占用的字节为标准,即以double型的weight为标准,所以Fruit类中int型的no不足8字节都会补足到8字节,所以no补了4字节。char型的key补了7字节。在Apple类中最大变量是int型的size,所以type补了3字节。
gcc就不是以这样的标准,gcc对齐重点两点,
1)变量的偏移位置是该变量所占内存的整数倍,如果不满足则补齐,size不满足,所以key补了3字节
2)所有变量占的字节数是最大变量所占字节的整数倍,如果不满足则补齐,所有type补了7字节。

相关文章

  • c++内存对齐--GeekBand

    c++中每个class包含两部分:数据和函数。对每个对象来说函数部分大家公用一份,而数据部分每个对象是独立的。所以...

  • golang 和 C++ 的内存对齐

    golang 和 C++的内存对齐,基本一致,记住规则和对应类型的 size 即可 内存对齐规则 有效对齐值是固定...

  • sizeof与字节对齐

    参考 【面试题】sizeof引发的血案编译器与字节对齐c 语言字节对齐问题详解C/C++内存对齐内存存取粒度C和C...

  • c++内存对齐

    1、为什么要进行内存对齐呢? 平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台...

  • sse中内存对齐问题

    c++ sse中无论声明栈内存还是堆内存都需要声明内存对齐,在VC++中:堆内存分配使用_aligned_mall...

  • 2.iOS底层学习之内存对齐

    学习了内存对齐之后的疑问?? 1.为啥要内存对齐?2.内存对齐的规则?3.内存对齐实例分析。 内存对齐的目的 上网...

  • 内存对齐

    本次主要讨论三个问题: 什么是内存对齐 内存对齐的好处 如何对齐 内存对齐 内存对齐是一种提高内存访问速度的策略。...

  • 关于C++内存对齐

    关于C++内存对齐 测试代码如下: instance 的地址为0X0015FE44,如下图所示 在内存中找到该地址...

  • C++之内存对齐

    什么是内存对齐 编译器为每个“数据单元”按排在某个合适的位置上。 C、C++语言非常灵活,它允许你干涉“内...

  • C/C++内存对齐

    在面试或工作中,经常会遇到内存对齐的问题。这里结合我的理解谈一谈对内存对齐的理解。 1. 为什么要内存对齐,不对齐...

网友评论

      本文标题:c++内存对齐--GeekBand

      本文链接:https://www.haomeiwen.com/subject/ryirdttx.html