• 关于C++内存对齐


    关于C++内存对齐


    C++11从标准层面引入了一些和内存对齐相关的特性,标准库也增加了对应的组件,这里稍微总结一下。

    取得某个类型的对齐值

    C++中的Object(对象)是指一块满足以下条件的内存区域:

    1. 具有size属性,即能用sizeof取其大小。
    2. 具有alignment属性,即能用alignof取其对齐量。这个在稍后有详细的阐述。
    3. 类型
    4. ……(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用于修饰类型,它有以下三种使用形式:

    1. alignas(expr),这里expr必须是一个编译期常量表达式,且应为2的整数次幂。
    2. alignas(Type),这个写法等价于alignas(alignof(Type))
    3. 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自己写一个,不过已经有下面的几种方案:

    1. operator new允许通过一个std::align_val_t类型的参数来显示给出对齐要求,然而这是C++17才引入的,暂时没法广泛使用。
    2. 二段式构造。先调用_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)

  • 相关阅读:
    Win7下IE 8内存保护可能导致ActiveX无法安装的问题及其解决方法
    为Windows Server 2000开发和部署ASP.NET 3.5的应用程序
    MOSS 2010:如何为列表设计Infopath表单用于编辑和显示
    Windows Live is designed for you, but maybe not for your browser
    Meet the new WSS SharePoint Foundation 2010
    MOSS 2010: Visual Studio 2010开发体验(3)——调试代码
    MOSS 2010:Visual Studio 2010开发体验(10)——列表开发之内容类型
    MOSS 2010:谁动了我的“共享服务”
    MOSS 2010:通过SharePoint Designer定制列表项的条件格式
    如何访问嵌套母版页中的控件
  • 原文地址:https://www.cnblogs.com/AirGuanZ/p/8098729.html
Copyright © 2020-2023  润新知