#include<iostream>
using namespace std;
class Test
{
int a;
double d;
char c;
};
int main()
{
cout<<sizeof(int)<<endl;
cout<<sizeof(double)<<endl;
cout<<sizeof(char)<<endl;
cout<<sizeof(Test)<<endl;
Test sobj;
Test *dobj = new Test();
cout<<dobj<<endl;
dobj++;
cout<<dobj<<endl;
cout<<sizeof(sobj)<<endl;
cout<<sizeof(dobj)<<endl;
return 0;
}
输出:
4
8
1
24
00380A08
00380A20
24
4
这里我的问题是当我们使用sizeof运算符打印类的大小时,它显示为24字节,因为没有应用填充它很清楚,但是当我看到地址之间的区别时它显示类大小为12字节,如何内存被分配.. ??
答案 0 :(得分:3)
地址是十六进制的(如A
所示)。 0x20是十进制的32:差异(十进制)不是20 - 8,它是32 - 8 = 24.
答案 1 :(得分:2)
首先,您的困惑来自以十六进制(基数为16)打印的地址。两个地址的不同部分是0x20(十进制为32)和0x08(十进制为8)。这两个数字之间的差异是0x18(十六进制),或十进制24。
其次,肯定会应用一些填充。基于各种类型大小的数字,在您的问题中,请考虑以下代码,它以三种不同的顺序定义结构的字段:
(实例http://coliru.stacked-crooked.com/a/eb6a1b3721b875f0)
#include <iostream>
struct Layout1 {
int a;
double b;
char c;
};
struct Layout2 {
int a;
char b;
double c;
};
struct Layout3 {
double a;
int b;
char c;
};
int main() {
std::cout << sizeof(Layout1) << "\n";
std::cout << sizeof(Layout2) << "\n";
std::cout << sizeof(Layout3) << "\n";
return 0;
}
请记住,在此示例中,double是8个字节,int是4个字节,char是1个字节。每个结构的布局如下,其中i
表示int的一个字节,c
表示char,d
表示double的一个字节。符号-
表示填充的一个字节。
1 1 1 1 1 1 1 1 1 1 2 2 2 2
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
i i i i - - - - d d d d d d d d c - - - - - - - // layout 1
i i i i c - - - d d d d d d d d // layout 2
d d d d d d d d i i i i c - - - // layout 3
在第一个布局中,double成员必须在8字节边界上对齐,因此在int成员之后得到4个字节的填充。整个结构必须具有与其成员的最严格对齐相同的对齐方式,即双重结构。因此,char成员后面有7个字节的填充。
在第二种布局中,double必须仍然在8字节边界上,但char不需要;它可以在int之后立即打包,在double之前只留下三个字节的填充。由于结构以double结尾,因此不需要结束填充。
在第三种布局中,double启动struct,int(具有4字节对齐)可以立即跟随它(因为8是4的倍数)。 char(单字节对齐)可以跟随int,但是整个struct需要在8字节边界上对齐,因此在char字段之后有3个字节的填充。
上面的程序将输出:
24
16
16