c++内存对齐

发布于:2024-07-30 ⋅ 阅读:(124) ⋅ 点赞:(0)

内存对齐

看下面的例子:

// 32位系统上
#include<stdio.h>
struct{
    int x;
    char y;
}s;

int main(){
    printf("%d\n", sizeof(s)); // 输出 8
    return 0;
}

32位系统上int是4字节, char是1字节, 上述一个结构体占用内存应该是 4+ 1=5byte. 但是结果却是8

为什么要内存对齐

一般的处理器以2,4,6,16字节甚至32字节为单位来取内存,即 内存存取粒度

以32位系统为例,存取粒度为4字节,该处理器只能从地址为4的倍数的内存开始读取数据。

内存对齐能够提高CPU读取数据的速度,减少CPU访问数据的出错性, 避免指针访问出错

对齐规则

对齐模数 gcc中默认对齐模数 #pargma pack(4)

有效对齐值(对齐单位): 给定值#pargma pack(4) 和结构体最长数据类型中较小的那个

对齐规则:

  1. 结构体第一个成员的偏移量为0, 以后每个成员相对于结构体首地址的offset都是该成员大小与有效对齐值中较小那个的整数倍, (如有需要编译器会在成员之间填充字节)
  2. 结构体总大小为 有效对齐值的整数倍
// 32位系统
#include<stdio.h>
struct {
    int i;
    char c1;
    char c2;
} x1;

struct{
    char c1;  
    int i;    
    char c2;  
}x2;

struct{
    char c1;  
    char c2; 
    int i;    
}x3;

int main(){
    printf("%d\n",sizeof(x1));  // 输出8
    printf("%d\n",sizeof(x2));  // 输出12
    printf("%d\n",sizeof(x3));  // 输出8
    return 0;
}

上述结构体中最长数据类型为int 4字节

以x2为例

  • c1 为1字节, 有效对齐单位4字节,则按照1 字节对齐,占用第0个单位
  • i 为4字节, 有效对齐单位4字节, 相较于首地址偏移要为4的倍数,所以在前一个数据类型后面填充,使得i偏移从4开始占用4字节(占用4,5,6,7单元)
  • c2 为1字节,有效对齐单位4字节,所以c相对于首地址偏移要为1的倍数,这个直接跟在i后面(占用第8单元)
  • 然后使用规则2,x2中最长数据类型占用为4字节,有效对齐单位也是4字节,所以整个x2结构体需要是4的倍数,现在占用了4+4+1=9个, 需要补齐,在后面填充3字节,

故而x2一共占用了12字节

在这里插入图片描述

各平台上各种数据类型大小;

16位 32位 64位
char 1个字节8位 1个字节8位 1个字节
short 2个字节16位 2个字节16位 2个字节
int 2个字节16位 4个字节32位 4个字节
long 4个字节32位 4个字节32位 8个字节
long long 8个字节 8个字节 8个字节
指针 2个字节 4个字节 8个字节
double 8个字节 8个字节 8个字节

参考:C/C++内存对齐详解


网站公告

今日签到

点亮在社区的每一天
去签到