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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· 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 让容器管理更轻松!