c++11总结10——内存对齐
1. 内存对齐的概念
内存对齐是一个数据类型所能存放的内存地址的属性。这个属性是一个无符号整数,并且这个整数必须是2的N次方(1、2、4、8、、、1024、、、)。
例如当我们说一个数据类型的内存对齐为8时,是指这个数据类型所定义出来的所有变量的内存地址都是8的倍数。
2. 自然对齐的概念
当一个基本数据类型的对齐属性和这个数据类型的大小相等时,称为自然对齐。例如一个4字节大小的int型数据,默认情况下字节对齐是4。
3. 为什么需要内存对齐?
1) 并不是每一个硬件平台都能随便访问任意位置的内存的。某些平台(例如Alpha等)若读取的数据未内存对齐,将拒绝访问或抛出异常。
2)将一个int放在奇数内存(例如1)位置上,如果想把4个字节读出来,32位CPU需要读取两次。如下例子所示:
如果按照4字节对齐后,一次就可以读取出来了,提升了效率。
4. 内存对齐示例
#include <iostream>
using namespace std;struct
{int i;char c1;char c2;
}Test1;struct {char c1;int i;char c2;
}Test2;struct {char c1;char c2;int i;
}Test3;int main()
{cout << sizeof(Test1) << endl;cout << sizeof(Test2) << endl;cout << sizeof(Test3) << endl;system("pause");return 0;
}
执行结果:
8
12
8
本例测试环境为vs2015,默认4字节对齐,分析如下所示:
5. 堆内存对齐
malloc一般使用当前平台默认的最大内存对齐数对齐内存,比如,MSVC在32位下一般为8字节对齐,64位下则是16字节对齐。如果我们自定义的内存对齐超出了这个范围,则不能直接使用malloc获取内存。
但当我们有需求需要分配一块具有特定内存对齐的内存块时,在MSVC下应使用_aligned_malloc,gcc下一般使用memalogn等函数。
实现一个简易的aligned_malloc:
inline void* aligned_malloc(size_t size, size_t alignment)
{//检查alignment是否为2^Nassert(!(alignment & (alignment - 1)));//计算出最大的offset,sizeof(void*)是为了存储原始指针地址size_t offset = sizeof(void*) + (--alignment);//分配一块带offset的内存char *p = static_cast<char*>(malloc(offset + size));if (!p)return nullptr;//通过"& (~alignment)"把多计算的offset减掉void* r = reinterpret_cast<void*>(reinterpret_cast<size_t>(p + offset) & (~alignment));//将r当作一个指向void*的指针,在r当前地址前面放入原始地址static_cast<void**>(r)[-1] = p;//返回经过对齐的内存地址return r;
}inline void align_free(void* p)
{//还原回原始地址,并freefree(static_cast<void**>(p)[-1]);
}
6. 利用alignas指定内存对齐的大小
例如:
alignas(32) long long a = 0;#define XX 1
struct alignas(XX)MyStruct {};
注意:alignas只能改大不能改小,如果需要改小,需要使用#prama pack(n),n为对齐字节数。
c++11中与#prama等价的为_Prama(微软暂不支持,vs中暂不能使用);
_Pragma("pack(1)")
struct MyStruct
{char a;int b;short c;long d;
};
_Pragma("pack()")
7. 利用alignof和std::alignment_of获取内存对齐的大小
struct MyStruct
{char c;int a;double b;
};int main()
{//获取内存对齐的大小cout << alignof(MyStruct) << endl; //8int alignSize = std::alignment_of<MyStruct>::value;cout << alignSize << endl; //8system("pause");return 0;
}
8. std::max_align_t和std::align操作符
1)std::max_align_t用来返回当前平台的最大默认内存对齐类型。
cout << alignof(std::max_align_t) << endl;
2)std::align用来在一大块内存当中获取一个符合指定内存要求的地址。
std::align的原型为:
void* align( std::size_t alignment,
std::size_t size,
void*& ptr,
std::size_t& space );
char buf[] = "-----------------";
void* p = buf;
std::size_t space = sizeof(buf) - 1;
std::align(alignof(int), sizeof(char), p, space);
在buf这个大内存块中,指定内存对齐为slignof(int),找一块sizeof(char)大小的内存,并且在找到这块内存后将地址放入p,将buf从p开始的长度当入space。
c++11总结10——内存对齐相关推荐
- C语言基础知识之define宏定义表达式,undef,内存对齐,a和a的区别,数组知识点,int (*)[10] p,二维数组参数与二维指针参数,函数指针数组,常见的内存错误及对策
一.用define宏定义表达式 1.定义一年有多少秒: #define SEC_A_YEAR 60*60*24*365 //上述描述不可靠,没有考虑到在16位系统下把这样一个数赋给整型变量的时候可能会 ...
- 内存对齐与sizeof
一.一个例子 #include <iostream> using namespace std; struct X1 { int i;//4个字节 char c1;//1个 ...
- [转]C++结构体|类 内存对齐详解
内存地址对齐,是一种在计算机内存中排列数据(表现为变量的地址).访问数据(表现为CPU读取数据)的一种方式,包含了两种相互独立又相互关联的部分:基本数据对齐和结构体数据对齐 . 为什么需要内存对齐?对 ...
- NumPy-快速处理数据--ndarray对象--多维数组的存取、结构体数组存取、内存对齐、Numpy内存结构...
本文摘自<用Python做科学计算>,版权归原作者所有. 上一篇讲到:NumPy-快速处理数据--ndarray对象--数组的创建和存取 接下来接着介绍多维数组的存取.结构体数组存取.内存 ...
- struc,union,class的内存对齐方式
首先思考一个问题:int,short,char的struct,这几个数应该怎么放,内存最小 strct ts { int a; short b; char c; }; 这样放最小,为8,这样放置,只会 ...
- 大小端、位段和内存对齐
关于C++中的大小端.位段(惑位域)和内存对齐 来源: ♂戚建建㊣的日志 听到好几个朋友说到去一些公司做面试,总是遇到关于大小端.位段(或者叫位域)和内存对齐的考题,然后就不知所措了.虽然我认为很多开 ...
- 总结面试时没有回答上的内存对齐问题
前两天面试某公司时,没有回答上的一个问题,总结如下,以供参考. 问:下面这个结构类型的实例变量占用多少内存: struct struct1 { int i; short j; ...
- C++ 内存对齐 及 引用是否真的节省内存的一点思考
文章目录 1. 内存对齐 2. 递归中的内存对齐 3. C++引用的本质 4. 致谢 1. 内存对齐 通过以下语句,获取变量的占用内存打下: cout << "size of i ...
- 内存对齐分配策略(含位域模式)
1:内存对齐定义: 现在使用的计算机中内存空间都是按照字节划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但是实际上计算机系统对于基本数据类型在内存 中的存放位置都有限制,要求 ...
最新文章
- “智享未来 知行合一”,开为科技AI产品发布会于2月6日召开
- opencv源码解析之(6):hog源码分析
- 普通行列转换(交叉表,横表变列表)
- linux6.4 dns 主从,dns正反解析与主从复制文件同步
- 每天一道LeetCode-----逆序链表
- 【VB测绘程序设计】第二章 VB测绘程序基础
- 三个好用的并发工具类
- oracle dblink 验证,Oracle DBLINK 简单使用
- 程序员到底会不会修电脑?
- 高效程序员的45个习惯の欲速则不达
- 树——二叉树的深层特性
- ENVI5.4 新增图像分类介绍
- Kafka 入门教程之一: 安装
- C语言课程设计|通讯录管理系统(含完整代码)
- 全志(Allwinner) A40i使用千兆网的配置
- 项目质量管理—七种基本质量工具
- 谷歌浏览器设置默认Flash
- 麦子学院IT资源,web前端,UI设计,Java全套,IOS,android,产品经理,pyhton,网络安全,运维
- 2003系统服务器不设置密码,服务器2003怎么设置密码
- 关于正向级数收敛而它的平方也收敛的证明