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 之间以及结构体末尾添加了填充字节以满足对齐要求。

相关推荐
WWJA王文举5 小时前
I²C通信完整流程详解:START、地址、ACK、数据、Repeated START和STOP一次讲透
c语言·开发语言
zhanghaha13145 小时前
Python进阶教程:6_JSON 数据解析 —— 新手完全指南
开发语言·python·json
qq_448011166 小时前
C语言中的动态内存分配
c语言·开发语言·php
动词ing7 小时前
【学习笔记】C语言(数组指针与指针数组+字符数组+函数+参数传递+字符串作为形参+递归函数+指针函数+回调函数+结构体嵌套+内存动态分配函数)
c语言·笔记·学习
汉字萌萌哒7 小时前
2024CSP-J入门级C++真题详解
开发语言·c++
arbboter7 小时前
【网络工具】NetProxy网络代理用户手册
开发语言·网络·c#·网络代理·网络异常·代理工具
汉字萌萌哒8 小时前
2019CCF-CSP入门级C++试题解析
java·开发语言·c++
叠层归一研究院8 小时前
AGI 系统(十一):二阶网络 — 二阶递归 × 多主体 (元符号网络)
开发语言·人工智能·算法·php·agi
小雨笙笙9 小时前
C语言:变量三属性——存储类型
c语言·开发语言
果果燕10 小时前
C++ 学习笔记(二):类与对象—— 构造函数与析构函数
开发语言·c++