关于C++内存对齐
关于C++内存对齐
C++11从标准层面引入了一些和内存对齐相关的特性,标准库也增加了对应的组件,这里稍微总结一下。
取得某个类型的对齐值
C++中的Object(对象)是指一块满足以下条件的内存区域:
- 具有size属性,即能用
sizeof取其大小。 - 具有alignment属性,即能用
alignof取其对齐量。这个在稍后有详细的阐述。 - 类型
- ……(lifetime等)
现在已经知道了每个对象都有其类型,这样的类型称为“对象类型”(object type)。每个对象类型都有一个alignment值,该值的类型为std::size_t,且总为2的整数次幂。我们可以通过关键字alignof或标准库中的std::alignment_of(声明位于头文件<type_traits>)获知此值,比如:
struct S { char a; double b }
int main(void)
{
cout << alignof(S) << endl;
cout << alignment_of<int>::value << endl;
}
C++17引入了std::alignment_of_v,允许这样的写法:
int main(void)
{
cout << alignment_of_v<double> << endl;
}
当然,只是语法糖而已。
指定类型的对齐规则
C++11引入了关键字alignas用于修饰类型,它有以下三种使用形式:
alignas(expr),这里expr必须是一个编译期常量表达式,且应为2的整数次幂。alignas(Type),这个写法等价于alignas(alignof(Type))。alignas(pack...),这里pack是个模板参数包,相当于对参数包中的每个元素P,同时以alignas(P)来修饰后面的类型。
下面看例子:
struct alignas(16) MyStruct
{
char ch;
};
int main(void)
{
MyStruct instanceOfMyStruct; //instanceOfMyStruct按16字节对齐
alignas(127 + 1) char charArray[128]; //charArray按128字节对齐
alignas(int) char ch; //ch按alignof(int)字节对齐
//...
}
堆上对象的内存对齐
我们已经能够指定某个类型的对齐规则了,但对于堆上申请下来的对象还缺乏控制。我们当然可以基于malloc自己写一个,不过已经有下面的几种方案:
operator new允许通过一个std::align_val_t类型的参数来显示给出对齐要求,然而这是C++17才引入的,暂时没法广泛使用。- 二段式构造。先调用
_aligned_malloc(Windows)或者posix_memalign(Posix)拿到一块内存,然后用placement new构造对象。
其他
C++11引入的std::aligned_storage(头文件<type_traits>中)用于获得一块按指定规则对齐的内存块。它相当于:
template<std::size_t Len, std::size_t Align>
struct aligned_storage
{
struct type
{
alignas(Align) unsigned char data[Len];
};
};
C++11引入的std::max_align_t:“std::max_align_t is a trivial type whose alignment requirement is at least as strict (as large) as that of every scalar type”,也就是任何一个scalar type的默认对齐大小都不会超过alignof(max_align_t)。
关于C++内存对齐的更多相关文章
- C++内存对齐总结
大家都知道,C++空类的内存大小为1字节,为了保证其对象拥有彼此独立的内存地址.非空类的大小与类中非静态成员变量和虚函数表的多少有关. 而值得注意的是,类中非静态成员变量的大小与编译器内存对齐的设置有 ...
- C/C++: C++位域和内存对齐问题
1. 位域: 1. 在C中,位域可以写成这样(注:位域的数据类型一律用无符号的,纪律性). struct bitmap { unsigned a : ; unsigned b : ; unsigned ...
- C/C++ 知识点1:内存对齐
预备知识:基本类型占用字节 在32位操作系统和64位操作系统上,基本数据类型分别占多少字节呢? 32位操作系统: char : 1 int :4 short : 2 unsigned ...
- Windows+GCC下内存对齐的常见问题
结构/类对齐的声明方式 gcc和windows对于modifier/attribute的支持其实是差不多的.比如在gcc的例子中,内存对齐要写成: class X { //... } __attrib ...
- c++内存对齐
内存对齐原则: 1.数据成员对齐规则:struct, union的数据成员,第一个数据成员放在offset为0的地方,之后的数据成员的存储起始位置都是放在该数据成员大小的整数倍位置.如在32bit的机 ...
- C语言中内存对齐
今天一考研同学问我一个问题,一个结构体有一个int类型成员和一个char类型成员,问我这个结构体类型占多少个字节,我直接编个程序给他看结果.这个结构体占八个字节,咦,当时我蛮纳闷的,一个int类型四个 ...
- 内存对齐 和 sizeof小结
数据对齐(内存对齐)指该数据所在的地址必须是该数据长度的整数倍.X86CPU能直接访问对齐的数据,当它试图访问未对齐的数据时,会在内部进行一系列的调整,降低运行速度.数据对齐一般出现在结构体和类中,在 ...
- 解析C语言结构体对齐(内存对齐问题)
C语言结构体对齐也是老生常谈的话题了.基本上是面试题的必考题.内容虽然很基础,但一不小心就会弄错.写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的 ...
- C语言再学习之内存对齐
昨天看Q3的代码,看到有个_INTSAIZEOF的宏,着实晕了一阵.一番google后,终于明白,这个宏的作用是求出变量占用内存空间的大小,先看看_INTSAIZEOF的定义吧: #define _I ...
- C结构体中数据的内存对齐问题
转自:http://www.cnblogs.com/qwcbeyond/archive/2012/05/08/2490897.html 32位机一般默认4字节对齐(32位机机器字长4字节),64位机一 ...
随机推荐
- kotlin之包
在kotlin中包的概念在表达方式上与Java完全一样,不过kotlin中的包和目录没有关系,kotlin包仅仅是为了引用文件中的资源而设计的. package loaderman.bar fun p ...
- linux的dos开关机命令
常用:halt.reboot CentOS关机命令: 重启命令 reboot shutdown -r now 立刻重启 shutdown -r 10 过10分钟自动重启 shutdown -r 20: ...
- 监控web80端口
判断本机的80端口是否开启着,如果开启着什么都不做,如果发现端口不存在,那么重启一下httpd服务,并发邮件通知你自己. #! /bin/bashmail=123@123.comif netstat ...
- ceph对接openstack环境(4)
ceph对接openstack环境 环境准备: 保证openstack节点的hosts文件里有ceph集群的各个主机名,也要保证ceph集群节点有openstack节点的各个主机名 一.使用rbd方式 ...
- innodb 隔离等级
前一段时间参加了一个国内知名公司的面试,被问及对数据库的了解,自感还不错,可谁知在隔离等级这种基本概念的点翻个船,也不是因为完全不懂,而是本来这里就比较晦涩,加之具体上次看这里的东西时候已经过了一年多 ...
- JavaScript抽象语法树英文对照
type:"Program" //顶级对象类型 type:"Identifier" // 标识符 type:"FuncationDeclaration ...
- phoenix创建表失败:phoenixIOException: Max attempts exceeded
下面的问题,搞了1天才解决,太坑了,在这里记录一下. 问题现像:执行命令后,1分钟没有返回, 然后报下面的错,偶尔会出现以下不同的报错信息. jdbc:phoenix:10.0.xx.1:2181&g ...
- 树莓派-CentOS-Minimal arm版的设置
将镜像用 balenaEtcher 写入到树莓派SD卡并启动后,需要对其进行一些设置才能正常使用. 1. 用户名 root 密码 centos 2. 扩展 rootfs 到最大可用空间:cat REA ...
- Spring Cloud(2):服务发现(Eureka)
Spring Cloud Eureka是Spring Cloud Netflix项目下的一个模块,作用是服务的注册和发现,并实现服务治理.它有一个(或一组,以实现高可用)服务注册中心(eureka s ...
- 部署 --- Docker
Docker学习 介绍 : Docker速度更快.性能更高.操作更易.我们开发的不同的程序APP是需要在操作系统中单独的环境中隔离运行的. 为了能让我们不同的程序可以在隔离的环境中运行:我们可以使用虚 ...