问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

(C语言进阶)结构体内存对齐和修改默认对齐数

创作时间:
作者:
@小白创作中心

(C语言进阶)结构体内存对齐和修改默认对齐数

引用
CSDN
1.
https://blog.csdn.net/2301_79580018/article/details/134779800

在C语言中,结构体的内存对齐是一个重要的概念,它影响着程序的性能和内存使用效率。本文将详细介绍结构体的内存对齐机制,解释为什么需要内存对齐,以及如何通过修改默认对齐数来优化内存使用。

一.结构体内存对齐

结构体内存大小计算方法:

偏移量:是指某个成员在结构体中相对于结构体首地址的偏移字节数。在计算机中,结构体是一种自定义数据类型,它由多个不同类型的成员组成。每个成员在内存中的存储位置是连续的,而结构体本身在内存中的存储位置也是连续的。因此,计算某个成员的偏移量可以帮助我们更好地理解结构体在内存中的存储方式。

例一:

例二:

例三:

嵌套的结构体会对齐到自己的最大对齐数,结构体整体大小为所有元素对齐数的最大值的整数倍

二.为什么存在内存对齐

内存对齐的主要目的是提高访问效率。现代计算机的内存系统通常以字(word)为单位进行访问,而字的大小通常是2的幂次方(如2、4、8字节)。如果数据没有正确对齐,处理器可能需要进行多次内存访问才能读取一个完整的数据项,这会显著降低性能。

此外,某些硬件平台甚至不允许非对齐访问,尝试这样做会导致硬件异常。

三.节省空间的方法

虽然内存对齐可以提高性能,但有时我们也需要优化内存使用。可以通过以下方式来节省空间:

  1. 重新排列结构体成员,将小的成员放在大的成员后面
  2. 使用#pragma pack指令来调整对齐数

四.修改默认对齐数

默认情况下,编译器会根据目标平台的特性选择一个合适的对齐数。但有时我们可能需要手动调整这个值,以优化内存使用或满足特定需求。

例一:

修改前:

#include<stdio.h>
#include<stddef.h>
typedef struct S1
{
    int a;
    double b;
}S1;
int main()
{
    printf("%zu\n",offsetof(S1,a));
    printf("%zu\n", offsetof(S1,b));
    printf("%zu",sizeof(S1));
    return 0;
}

修改后:

#include<stdio.h>
#include<stddef.h>
#pragma pack(4)
typedef struct S1
{
    int a;
    double b;
}S1;
#pragma pack()
int main()
{
    printf("%zu\n",offsetof(S1,a));
    printf("%zu\n", offsetof(S1,b));
    printf("%zu",sizeof(S1));
    return 0;
}

例二:

修改前:

#include<stdio.h>
#include<stddef.h>
typedef struct S1
{
    int a;
    char b;
    double c;
}S1;
int main()
{
    printf("%zu\n",offsetof(S1,a));
    printf("%zu\n", offsetof(S1,b));
    printf("%zu\n", offsetof(S1,c));
    printf("%zu",sizeof(S1));
    return 0;
}

修改后:

#include<stdio.h>
#include<stddef.h>
#pragma pack(1)
typedef struct S1
{
    int a;
    char b;
    double c;
}S1;
#pragma pack()
int main()
{
    printf("%zu\n",offsetof(S1,a));
    printf("%zu\n", offsetof(S1,b));
    printf("%zu\n", offsetof(S1,c));
    printf("%d",sizeof(S1));
    return 0;
}

本文原文来自CSDN

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号