C语言的结构体在内存中是如何存放的?

目录

      • [1. 顺序存储:](#1. 顺序存储:)
      • [2. 对齐(Alignment):](#2. 对齐(Alignment):)
      • [3. 填充(Padding):](#3. 填充(Padding):)
      • [4. 结构体整体对齐:](#4. 结构体整体对齐:)
      • [5. 强制对齐:](#5. 强制对齐:)
      • 示例:

C语言中的结构体在内存中的存储方式由以下几个关键概念决定:

1. 顺序存储:

结构体的成员变量按照它们在定义中出现的顺序存储在内存中。假设我们有以下结构体:

c 复制代码
typedef struct {
    char a;
    int b;
    char c;
} MyStruct;

在这种情况下,成员变量在内存中的存放顺序为:abc

2. 对齐(Alignment):

为了提高访问速度,现代计算机体系结构通常要求特定类型的数据在特定的边界上对齐。对齐规则的具体实现依赖于系统架构和编译器设置,但常见的规则如下:

  • char 类型通常在 1 字节边界对齐。
  • int 类型通常在 4 字节边界对齐。
  • double 类型通常在 8 字节边界对齐。

3. 填充(Padding):

由于对齐规则的存在,结构体中可能会出现"空隙"或者"填充"字节,以确保每个成员变量都对齐到正确的边界上。这些填充字节不可避免地会增加结构体的总大小。

举个例子:

c 复制代码
typedef struct {
    char a;   // 1 byte
    int b;    // 4 bytes (通常情况下)
    char c;   // 1 byte
} MyStruct;

在上面的例子中,char a 之后是 int b,而 int 需要 4 字节对齐。因为 char a 只占用 1 个字节,所以在 int b 之前会有 3 个字节的填充,使得 b 在 4 字节边界对齐。接下来,char c 不需要额外的填充。总大小为 8 字节(1+3+4+1)。

4. 结构体整体对齐:

结构体的总大小也会根据其最大成员的对齐需求进行对齐。以确保数组的每个元素都能按照最大成员的对齐方式对齐。

例如,如果我们有以下结构体:

c 复制代码
typedef struct {
    char a;   // 1 byte
    int b;    // 4 bytes
    double c; // 8 bytes
} MyStruct2;

假设 char 对齐为 1 字节,int 对齐为 4 字节,double 对齐为 8 字节。成员变量的内存布局如下:

  • a:1 字节(偏移量 0)
  • 填充:3 字节(使 b 对齐到 4 字节边界)
  • b:4 字节(偏移量 4)
  • c:8 字节(偏移量 8,无需填充)

总大小为 16 字节,MyStruct2 的每个实例都会对齐到 8 字节边界,因为 c 是最大成员,其对齐需求为 8 字节。

5. 强制对齐:

在某些情况下,可以使用编译器指令或编译器特定的关键词(如 #pragma pack__attribute__((packed)))来更改结构体的默认对齐方式,减少填充字节,但这样做可能会降低访问速度。

示例:

以下示例代码展示了结构体在内存中的分布和大小计算:

c 复制代码
#include <stdio.h>

typedef struct {
    char a;   // 1 byte
    int b;    // 4 bytes
    char c;   // 1 byte
} MyStruct;

int main() {
    printf("Size of MyStruct: %zu\n", sizeof(MyStruct));
    return 0;
}

输出结果:

复制代码
Size of MyStruct: 12

这表明,编译器为 bc 之间以及结构体末尾添加了填充字节以满足对齐要求。

相关推荐
Alice-YUE26 分钟前
【js高频八股】防抖与节流
开发语言·前端·javascript·笔记·学习·ecmascript
云泽80830 分钟前
C++11 核心特性全解:列表初始化、右值引用与移动语义实战
开发语言·c++
froginwe111 小时前
DOM 加载函数
开发语言
Hello eveybody1 小时前
介绍一下背包DP(Python)
开发语言·python·动态规划·dp·背包dp
AI进化营-智能译站1 小时前
ROS2 C++开发系列12-用多态与虚函数构建可扩展的ROS2机器人行为模块
开发语言·c++·ai·机器人
iCxhust1 小时前
微机原理实践教程(C语言篇)---A002流水灯
c语言·开发语言·单片机·嵌入式硬件·51单片机·课程设计·微机原理
qeen872 小时前
【数据结构】建堆的时间复杂度讨论与TOP-K问题
c语言·数据结构·c++·学习·
莎士比亚的文学花园2 小时前
Linux驱动开发(3)——设备树
开发语言·javascript·ecmascript
图码2 小时前
如何用多种方法判断字符串是否为回文?
开发语言·数据结构·c++·算法·阿里云·线性回归·数字雕刻
U盘失踪了2 小时前
python curl转python脚本
开发语言·chrome·python