Boost.Align本模块主要的功能是提供一系列的函数、类、模板、特性和宏等来控制、审查和诊断内存对齐。
C++11为class类型添加了增长对齐类型(over-alignment),但是C++标准库中的new运算符、表达式和默认的分配器、std::allocator并不支持为over-aligned的数据动态分配内存。boost提供库来提供函数和分配器来支持over-aligned的数据。
aligned_free(pointer)
代替了::operator delete(pointer, std::nothrow)
aligned_allocator
代替了std::allocator
aligned_allocator_adaptor
代替了 Allocator的使用
aligned_delete
代替了std::default_delete
C++11标准提供了std::align
来对齐指针的值,但是(libstdc++直到gcc4.8.0)并没有支持实现,msvc11.0错误的实现了它,Boost库实现了这些,为C++03编译器也提供了std::align
C++11标准库提供了std::alignment_of
的特性来查询对齐所需的类型,但是直到libc++(clang3.4),并没有为数组的类型正确的提供,在msvc14.0中会给数组类型返回错误的值。Boost库实现了这些,为C++03编译器也提供了实现。
分配对齐的内存有时不足以确保生成最佳代码。开发人员使用特定的编译器内在函数来通知编译器内存块的给定对齐属性。该库提供了一个宏 , BOOST_ALIGN_ASSUME_ALIGNED
来为具有适当内在函数的编译器抽象该功能。
该库提供了一个函数,is_aligned
用于测试指针值的对齐情况。在断言中验证内存是否正确对齐通常很有用。
包含头文件: boost/align/align.hpp
功能: 对齐一块内存并返回首地址(指针对齐)
接口:
void* align(std::size_t alignment, std::size_t size, void*& ptr, std::size_t& space)
输入参数:
alignment 应当为2的幂,为存储空间对齐的边界值。
size 为对齐内存的长度
ptr 为对齐内存后的起始内存地址指针
space 为对齐内存后的占用大小(长度)
以alignment为对齐边界申请连续size字节的内存,ptr输入时是起始地址,处理完之后是对齐之后的内存空间首地址,space会减少本来偏移的空间字节数(因为ptr不一定正好在以alignment指定的对齐边界上,故需要做偏移)。
实例:
#include
#include
int main(int argc, char** argv) {
void* stroge;
size_t space = 5000;
//按512字节对齐的方式,开辟2000个连续的空间,stroge最初值为0xcccccccccccccccc,本身没有在对齐边界上,需要偏移308个字节地址达到边界,space相应减少308,开辟2000个字节的内存地址,space至少能满足2308的大小。返回的地址就是0xccccccccccccce00,newPtr与stroge的值都是此
void* newPtr = boost::alignment::align(512, 2000, stroge, space);
return 0;
}
包含头文件:
功能: 返回一个大于等于value的对齐边界(alignment)倍数的值。
接口:
template constexpr T align_up(T value, std::size_t alignment) noexcept;
输入参数:
输出参数:
包含头文件:
功能: 返回一个小于等于value的对齐边界(alignment)倍数的值。
接口:
template constexpr T align_up(T value, std::size_t alignment) noexcept;
输入参数:
输出参数:
实例:
#include
#include
#include
#include
int main(int argc, char** argv) {
size_t bound = 567;
//输出1024
size_t retUp = boost::alignment::align_up(bound, 512);
//输出512
size_t retDown = boost::alignment::align_down(bound, 512);
return 0;
}
包含头文件:
功能: 分配指定对齐方式的连续内存
接口:
void* aligned_alloc(std::size_t alignment, std::size_t size);
输入参数
返回
包含头文件:
功能: 释放对齐内存指针
接口:
void aligned_free(void* ptr);
输入参数
返回
包含头文件:
功能: 判断某指针指向的连续空间是否按照指定的对齐方式对齐。
接口:
bool is_aligned(const volatile void* ptr, std::size_t alignment) noexcept;
template constexpr bool is_aligned(T value, std::size_t alignment) noexcept;
输入参数
返回
实例:
#include
#include
#include
#include
int main(int argc, char** argv) {
void* storage = boost::alignment::aligned_alloc(32, 1000);
if (boost::alignment::is_aligned(storage, 32)) {
boost::alignment::aligned_free(storage);
}
return 0;
}
包含头文件:
构造函数:
aligned_allocator() = default;
template aligned_allocator(const aligned_allocator&) noexcept;
成员函数:
pointer allocate(size_type size, const_void_pointer = 0);
std::bad_alloc
的异常void deallocate(pointer ptr, size_type);
size_type max_size() const noexcept;
包含头文件:
构造函数:
aligned_allocator_adaptor() = default;
//使用Allocator的基类std::forward(alloc)初始化
template aligned_allocator_adaptor(A&& alloc) noexcept;
template aligned_allocator_adaptor(const aligned_allocator_adaptor& other) noexcept;
成员函数:
Allocator& base() noexcept;
const Allocator& base() const noexcept;
pointer allocate(size_type size);
pointer allocate(size_type size, const_void_pointer hint);
hint
是通过调用allocate()
获得指针。void deallocate(pointer ptr, size_type size);
包含头文件:
成员运算符:
template void operator()(T* ptr) noexcept(noexcept(ptr->~T()));
功能: 利用析构函数调用aligned_free()
将参数指针释放。
alignment_of
template struct alignment_of;
包含头文件:
参考值说明:
T是类模板,需要T作为一个整数常量代表类型的size(std::size_t),T是一个引用数组类型时,要求数组是对齐存储的,而且元素值也是对齐类型的。
BOOST_ALIGN_ASSUME_ALIGNED
包含头文件:
定义:
BOOST_ALIGN_ASSUME_ALIGNED(ptr, alignment)
功能: 断言ptr的内存空间是否按要求对齐
//1.对齐空间分配
//alignment对齐边界 2的幂
//size 字节数
void* storage = boost::alignment::aligned_alloc(alignment, size);
//释放空间
boost::alignment::aligned_free(storage);
//2.对齐分配器allocator
//遵循over-alignment的分配
std::vector > vector;
//指定动态分配的最小对齐边界的范例
std::vector > vector;
//3.对齐内存分配器适配器
//将分配器类转换成适配器对象,遵循over-alignment对齐方式
boost::alignment::aligned_allocator_adaptor second(first);
//为动态分配指定最小的对齐方式值
boost::alignment::aligned_allocator_adaptor second(first);
//4.对齐删除器
//一个删除器应该与aligned_alloc成对使用
std::unique_ptr pointer;
//5.指针对齐
//算法起始指针,返回对齐后的地址指针
void* pointer = storage;
//给定的空间
std::size_t space = size;
void* result = boost::alignment::align(64, sizeof(double), pointer, space);
//6.查询对齐
//编译期间获知是否根据给定类型对齐
boost::alignment::alignment_of::value
//7.宏断言对齐
BOOST_ALIGN_ASSUME_ALIGNED(pointer, 64)
//8.条件检查对齐
assert(boost::alignment::is_aligned(pointer, 64));