技术解析

求教大佬们一个内存对齐的问题(c++ centos7 64 位系统)
0
1975-02-22 10:59:09
idczone
/*
说明:程序是在 centos7 64 位系统下测试的
*/
#include 

using namespace std;

struct A
{
    short var; 
    int var1;  
    long var2; 
    char var3; 
    string s;  
};

int main()
{
    short var;抗投诉服务器
    int var1;
    long var2;
    char var3;
    string s;
    A ex1;
    cout << sizeof(var) << endl;  // 2 short
    cout << sizeof(var1) << endl; // 4 int
    cout << sizeof(var2) << endl; // 8 long
    cout << sizeof(var3) << endl; // 1 char
    cout << sizeof(s) << endl;    // 8 string
    cout << sizeof(ex1) << endl;  // 32 struct
    return 0;
}

输出结果:

[root workspace]#./align
2
4
8
1
8
32

这里对齐怎么搞成了占用 32 个字节呢? 按照 8 字节对齐的话,5*8 = 40 字节 难道第一个 short 和 var1 共同占用 8 个字节? ( short 后面填充两个字节)


自己顶一下,大佬们都休息了吗

是的,可以搜索一下“C++ 内存对齐”

第一个 short 和 var1 共同占用 8 个字节。把 struct A 的 var2 放到第一位,对其后就占用 24 个字节了。
@csfreshman

内存对齐基本上可以概括成一个字段的起始地址能被 min {字段大小, 体系字长} 整除

啥意思?把 var2 放第一行有啥区别?还是占 32 个字节吧,我跑了下还是 32 个字节。

var1:0-2
var2:4-8
var3:8-16
var4:16-17
var5:24-32
起始偏移要是成员大小的整数倍。

一般结构体里面 考虑对齐的话建议由大到小的顺序摆放 你可以画个图来推演一下 ,对于 struct A 的话( 64bit ):
最小空间:8, 8, 4, 2, 1 = 24 bytes,4 、2 、1 在一个字节里

说错了 4 、2 、1 在一个 8 字节里

我的结果是
```
2
4
8
1
32
56
```
Manjro-Linux 64-bit, g++ (GCC) 10.2.0

2
4
4
1
24
40
VS

每个类型都有一个对齐值,一般是类型所占内存大小。结构体也有个对齐值,就是结构体成员的对齐值的最大值。
在进行内存对齐的时候要满足以下要求:
- 结构体长度要能够整除结构体的对齐值
- 结构体中成员地址到结构体首地址的偏移量要能够整除该成员的对齐值
回到这个问题上来:
- short 的长度是 2 字节,所以对齐值也是 2 字节,偏移量为 0,所以不用处理
- int 的长度是 4 字节,但是偏移量是 2 字节(前面成员的所占长度),所以要将偏移量补到( 2+2 ) 4 字节
- long 的长度是 8 字节,偏移量是( 2+2+4 ) 8 字节,可以整除 8,,满足条件
- char 的长度是 1 字节,偏移量是( 2+2+4+8 ) 16 字节,满足条件
- string 的长度是 8 字节,偏移量是( 2+2+4+8+1 ) 17 字节,不满足条件,所以将偏移量补到( 17+7 ) 24 字节
最后总的长度是( 2+2+4+8+1+7+8 ) 32 字节,并且这个长度能够除以结构体的对齐值( 8 ),所以对齐之后的长度就是 32 字节。

pack(push,1)
struct A
{
short var;
int var1;
long var2;
char var3;
string s;
};
pack(pop)

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服