C语言内存对齐总结
2015-12-31 16:04
323 查看
一、为什么会存在内存对齐
假设内存的数据位宽是32bit,cpu发出的0,1,2,3地址在内存芯片看来都是0地址,因为内存芯片是32bit位宽的,即cpu发出的地址的低2bit内存芯片是看不到的。此时,如果我一个int型变量的地址在cpu内存空间的1地址上,cpu发出1地址,会造成两次内存读取命令,第一次从内存的0地址取4字节,第二次从内存的1地址读取4字节,拼凑出所需的int变量。两次访问造成浪费,若内存对齐则不会存在这个问题。
二、结构体的对齐原则
1、结构体成员变量对齐原则
a. 第一个成员变量的地址就是结构体的地址
b. #pragma pack(n)和成员变量长度之间的较小值作为此成员变量的对齐值。
2、结构体整体的对齐原则
结构体中长度最长的成员变量的长度和#pragma pack(n)之间的较小值作为整体的对齐值。
三、举例
此时结构体大小为12。
此时结构体大小为8。
四、关于默认#pragma pack(n)
不同编译器的#pragma pack(n)都有一个默认值,#pragma pack(n)的值也不是随意设置的,编译器可能支持某些特定的数。
可以将#pragma pack(n)理解为:对齐值的最低要求,如果本身比#pragma pack(n)还小,那么就按你自身的长度作为对齐值。
注:只是自己的理解,有错的话还请提醒我。谢谢!
假设内存的数据位宽是32bit,cpu发出的0,1,2,3地址在内存芯片看来都是0地址,因为内存芯片是32bit位宽的,即cpu发出的地址的低2bit内存芯片是看不到的。此时,如果我一个int型变量的地址在cpu内存空间的1地址上,cpu发出1地址,会造成两次内存读取命令,第一次从内存的0地址取4字节,第二次从内存的1地址读取4字节,拼凑出所需的int变量。两次访问造成浪费,若内存对齐则不会存在这个问题。
二、结构体的对齐原则
1、结构体成员变量对齐原则
a. 第一个成员变量的地址就是结构体的地址
b. #pragma pack(n)和成员变量长度之间的较小值作为此成员变量的对齐值。
2、结构体整体的对齐原则
结构体中长度最长的成员变量的长度和#pragma pack(n)之间的较小值作为整体的对齐值。
三、举例
#include <stdio.h> typedef struct { char a; int b; char c; } type_t; int main(void) { printf("%d\n", sizeof(type_t)); }
此时结构体大小为12。
#include <stdio.h> #pragma pack(2) typedef struct { char a; int b; char c; } type_t; int main(void) { printf("%d\n", sizeof(type_t)); }
此时结构体大小为8。
四、关于默认#pragma pack(n)
不同编译器的#pragma pack(n)都有一个默认值,#pragma pack(n)的值也不是随意设置的,编译器可能支持某些特定的数。
可以将#pragma pack(n)理解为:对齐值的最低要求,如果本身比#pragma pack(n)还小,那么就按你自身的长度作为对齐值。
注:只是自己的理解,有错的话还请提醒我。谢谢!
相关文章推荐
- VS2013 C++ 动态链接库的生成
- c语言
- C语言中的函数传递
- C++类中静态变量和静态方法使用介绍
- Something about CPP
- 二叉堆--C语言实现
- C++ 学习路线和看法
- pandas安装若干异常及解决方案总结
- :/coolpigs//Visual Studio 2010 "工具">"选项"中的VC++目录编辑功能已被否决
- c++ typedef使用
- C语言的数据、常量和变量
- C语言位操作
- C++ 学习(右值引用, std::move)
- C/C++ 多种方式进行大小写字母转换
- 如何成为一个优秀的高级C++程序员
- C++11中的std::bind
- 大牛建议——C++学习建议
- C++继承、虚继承、虚函数类的大小问题
- 一.C语言:关键字、标识符和注释
- C++ 高性能无锁日志系统