C++结构体内幕揭秘:sizeof之谜与内存布局探秘
  KxE3CZnPt4x3 2024年03月23日 67 0

 

概述:C++结构体的`sizeof`不总是等于每个成员的`sizeof`之和,因为对齐和填充影响了内存布局。未对齐的结构体可能存在间隙,而对齐的结构体会插入填充以保持对齐。通过示例展示了结构体的内存对齐和填充,以及如何使用模板元编程打印结构体成员的偏移量,深入理解内存布局。

在C++中,结构体的sizeof并不总是等于每个成员的sizeof之和,这是由于对齐和填充的影响。编译器为了提高内存访问速度,通常会在结构体成员之间插入一些填充字节以对齐数据。

基础功能:

示例源代码:

#include <iostream>

// 未进行对齐的结构体
struct WithoutPadding {
    char a;    // 1 字节
    int b;     // 4 字节
    char c;    // 1 字节
};

// 进行对齐的结构体
struct WithPadding {
    char a;    // 1 字节
    char padding[3];  // 对齐填充 3 字节
    int b;     // 4 字节
    char c;    // 1 字节
};

int main() {
    std::cout << "WithoutPadding 大小:" << sizeof(WithoutPadding) << std::endl;
    std::cout << "WithPadding 大小:" << sizeof(WithPadding) << std::endl;

    return 0;
}

在这个示例中,WithoutPadding 结构体的大小是 6 字节(1 + 4 + 1),而WithPadding 结构体的大小是 12 字节(1 + 3(填充)+ 4 + 1)。这是因为编译器为了对齐int类型的成员b,在其前面插入了3字节的填充。

高级功能:

示例源代码:

#include <iostream>
#include <type_traits>

template <typename T>
void PrintOffsets() {
    std::cout << "Offsets for " << typeid(T).name() << ":" << std::endl;

    size_t offset = 0;
    size_t size = sizeof(T);

    // 使用模板元编程逐个打印成员的偏移量
    // 对于 C++17,可以使用 std::is_standard_layout<T> 确保是标准布局类型
    if constexpr (std::is_standard_layout<T>::value) {
        while (offset < size) {
            std::cout << "  Offset of member at index " << offset << ": " << offsetof(T, offset) << std::endl;
            offset++;
        }
    } else {
        std::cout << "  Not a standard layout type." << std::endl;
    }

    std::cout << std::endl;
}

struct ExampleStruct {
    char a;    // 1 字节
    int b;     // 4 字节
    char c;    // 1 字节
};

int main() {
    PrintOffsets<ExampleStruct>();

    return 0;
}

在这个示例中,PrintOffsets 函数使用模板元编程逐个打印结构体成员的偏移量。ExampleStruct 结构体包含了对齐填充,通过offsetof宏可以获取每个成员的偏移量。这有助于理解结构体内存布局的细节。

通过这两个示例,展示了结构体大小不等于成员sizeof之和的原因,以及如何使用模板元编程逐个打印结构体成员的偏移量。这些知识有助于理解内存对齐和结构体内存布局。

 

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2024年03月23日 0

暂无评论

推荐阅读
  H5oyQecqjP4R   24天前   34   0   0 C语言
  fHBiUfJyY67V   20天前   16   0   0 C语言
  V88gxnVgnp1F   8天前   50   0   0 C语言
  o1ZcTI9mJsxK   8天前   57   0   0 C语言
  TfjjLvnv5b8J   25天前   20   0   0 C语言
KxE3CZnPt4x3