02_32位和64位系统下 int、char、long、double所占的内存以及内存字节对齐问题

32位和64位系统下 int、char、long、double所占的内存以及内存字节对齐问题

    8字节为上限

C类型 30位机器(字节) 64位机器(字节)
char 1 1
short 2 2
int 4 4
long int 4 8
long long 8 8
char * 4 8
float 4 4
double 8 8

 


 

 

复制代码
 
#include<stdio.h>
struct A
{
    int   a;
    char  b;
    double c;
    char  d;
};
 
struct B
{
    char  a;
    double b;
    char  c;
};
 
int main()
{
    printf("int =%lu,char=%lu,double=%lu\n",sizeof(int),sizeof(char),sizeof(double));
    printf("structA=%lu  structB=%lu\n",sizeof(struct A),sizeof(struct B));
    return 0;
}
//64位   最多可以8位字节对齐      (先4位,遇8位变8位对齐)
//32位   最多可以4位字节对齐
复制代码
复制代码
//64位编译输出:

int =4,char=1,double=8
structA=24  structB=24

//    structA: 4+(1+3)+8+(1+7) = 24
//    structB: (1+7)+8+(1+7) = 24
//未遇到8位数据类型时时4字节对齐,遇到8字节数据类型变为8字节对齐

//32位编译输出:

int =4,char=1,double=8
structA=20  structB=16

//    struct A : 4+(1+3)+8+(1+3) = 20
//    struct B : (1+3)+8+(1+3) = 16
//不管怎么样都只能是4字节对齐
复制代码

 

结构体字节对齐问题:
  未进行特殊说明时,按照结构体中size最大成员对齐
  当进行对应字节对齐说明后,按照说明要求字节对齐

 

阿秀笔记:

    c++11以后引入两个关键字 alignas与 alignof。其中 alignof 可以计算出类型的对齐方式, alignas 可以指定结构体的对齐方式。
    但是 alignas 在某些情况下是不能使用的,具体见下面的例子

复制代码
// alignas 生效的情况
struct Info {
uint8_t a;
uint16_t b;
uint8_t c;
};
std::cout << sizeof(Info) << std::endl; // 6 2 + 2 + 2
std::cout << alignof(Info) << std::endl; // 2



struct alignas(4) Info2 {
uint8_t a;
uint16_t b;
uint8_t c;
};
std::cout << sizeof(Info2) << std::endl; // 8 4 + 4
std::cout << alignof(Info2) << std::endl; // 4
//☄   alignas 将内存对齐调整为4个字节。所以 sizeof(Info2) 的值变为了8
复制代码

 

复制代码
// alignas 失效的情况
struct Info {
uint8_t a;
uint32_t b;
uint8_t c;
};
std::cout << sizeof(Info) << std::endl; // 12 4 + 4 + 4
std::cout << alignof(Info) << std::endl; // 4
struct alignas(2) Info2 {
uint8_t a;
uint32_t b;
uint8_t c;
};
std::cout << sizeof(Info2) << std::endl; // 12 4 + 4 + 4
std::cout << alignof(Info2) << std::endl; // 4
//☄   若 alignas 小于自然对齐的最小单位,则被忽略。
复制代码

 

☄   如果想使用单字节对齐的方式,使用 alignas 是无效的。应该使用 #pragma pack(push,1) 或者使用__attribute__((packed)) 。

复制代码
#if defined(__GNUC__) || defined(__GNUG__)
#define ONEBYTE_ALIGN __attribute__((packed))
#elif defined(_MSC_VER)
#define ONEBYTE_ALIGN
#pragma pack(push,1)
#endif
struct Info {
uint8_t a;
uint32_t b;
uint8_t c;
} ONEBYTE_ALIGN;
#if defined(__GNUC__) || defined(__GNUG__)
#undef ONEBYTE_ALIGN
#elif defined(_MSC_VER)
#pragma pack(pop)
#undef ONEBYTE_ALIGN
#endif
std::cout << sizeof(Info) << std::endl; // 6 1 + 4 + 1
std::cout << alignof(Info) << std::endl; // 6
复制代码

☄   确定结构体中每个元素大小可以通过下面这种方法:

复制代码
#if defined(__GNUC__) || defined(__GNUG__)
#define ONEBYTE_ALIGN __attribute__((packed))
#elif defined(_MSC_VER)
#define ONEBYTE_ALIGN
#pragma pack(push,1)
#endif
/**
* 0 1 3 6 8 9 15
* +-+---+-----+---+-+-------------+
* | | | | | | |
* |a| b | c | d |e| pad |
* | | | | | | |
* +-+---+-----+---+-+-------------+
*/
struct Info {
uint16_t a : 1;
uint16_t b : 2;
uint16_t c : 3;
uint16_t d : 2;
uint16_t e : 1;
uint16_t pad : 7;
} ONEBYTE_ALIGN;
#if defined(__GNUC__) || defined(__GNUG__)
#undef ONEBYTE_ALIGN
#elif defined(_MSC_VER)
#pragma pack(pop)
#undef ONEBYTE_ALIGN
#endif
std::cout << sizeof(Info) << std::endl; // 2
std::cout << alignof(Info) << std::endl; // 1
复制代码

 


    

posted @   尘落曦枫  阅读(1076)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示