首页 > 系统相关 >C语言学习: 结构体的内存对齐

C语言学习: 结构体的内存对齐

时间:2023-02-05 08:55:31浏览次数:39  
标签:short struct int C语言 char 内存 对齐

怎么对齐的? 是对齐他占用内存的倍数, 看下面的代码

int main() {
  typedef struct Person {
    char *name;
    int age;
    char *id;
  } Person;

  struct Person person = {.name="bennyhuo", .id="12113322222"};
View Code

指针变量占用八个字节,int占4个字节, 大家看到最后八个字节对应的是 id指针,前面有cc cc cc cc, 这四个字节就是内存对齐导致的。

换种写法,优化结构体对齐的问题。 从这个例子可以看出, 结构体定义不合理的话, 会导致内存浪费。

 1 typedef struct {
 2     char a; // 1
 3     char b; // 1
 4 //    __attribute((aligned(2))) int c; // 4 gcc only
 5 //    _Alignas(8) int c; // 4 c11
 6     int c;
 7     short d; // 2
 8     double e; // 8
 9   } Align;
10 
11   typedef struct {
12     char a; // 1
13     char b; // 1
14     short d; // 2
15     int c; // 4
16     double e; // 8
17   } OptimizedAlign;
18 
19 
20   Align align = {'a', 'b', 3, 4, 5.0};
21   OptimizedAlign optimized_alignlign = {'a', 'b', 4, 3, 5.0};

看下面的内存分配, 第一版, int c 在short d前面,int 展占4位, short占2位,double占八位, 所以在分配e的时候,会让出6个cc, 放在第二行第八位,导致了红框部分内存的浪费。

align 和optimizeAlign,的区别, 就是把d移到c的前面定义, 这样, char, char, short, 就正好放在前四个字节上, int正好4个字节, 就避免了红框部署的浪费。

 

 

 怎么设置全局的内存对齐。

#pragma pack(2)

 

 

 设置前

 

 

 设置后, id指针的位置向前移了, 他变成2的倍数进行对齐, 而不是八位对齐。

 

 

 怎么设置单个字段的对齐方式呢: _Alignas

_Alignas(8) int c; // 4 c11
 1 typedef struct {
 2     char a; // 1
 3     char b; // 1
 4 //    __attribute((aligned(2))) int c; // 4 gcc only
 5     _Alignas(8) int c; // 4 c11
 6 //    int c;
 7     short d; // 2
 8     double e; // 8
 9   } Align;
10 
11   typedef struct {
12     char a; // 1
13     char b; // 1
14     int c; // 4
15     short d; // 2
16     double e; // 8
17   } OptimizedAlign;
18 
19 
20   Align align = {'a', 'b', 3, 4, 5.0};
21   OptimizedAlign optimized_alignlign = {'a', 'b', 4, 3, 5.0};
View Code

对齐前后,可以看到,上面的绿色部分是设置了八位对齐,下面的绿色部分是默认, 我们把int c改成八位对齐, 所以变成下面这样。

 

 

 怎么看一个字段对于这个结构体的内存偏移量: 用 offsetof(Align,e)

 

 

 整体代码

 1 #include <stdio.h>
 2 #include <io_utils.h>
 3 #include <stddef.h>
 4 //#pragma pack(2)
 5 int main() {
 6   typedef struct Person {
 7     char *name;
 8     int age;
 9     char *id;
10   } Person;
11 
12   struct Person person = {.name="bennyhuo", .id="12113322222"};
13 
14   PRINT_INT(person.age);
15   person.age = 30;
16 
17   typedef struct {
18     char a; // 1
19     char b; // 1
20 //    __attribute((aligned(2))) int c; // 4 gcc only
21     _Alignas(8) int c; // 4 c11
22 //    int c;
23     short d; // 2
24     double e; // 8
25   } Align;
26 
27   typedef struct {
28     char a; // 1
29     char b; // 1
30     int c; // 4
31     short d; // 2
32     double e; // 8
33   } OptimizedAlign;
34 
35 
36   Align align = {'a', 'b', 3, 4, 5.0};
37   OptimizedAlign optimized_alignlign = {'a', 'b', 4, 3, 5.0};
38 
39   //PRINT_INT(_Alignof(align.c));
40   PRINT_INT(offsetof(Align, e));
41   return 0;
42 }
View Code

结果

为什么要有内存对齐? 内存对齐之后, CPU访问内存会快一些

 

标签:short,struct,int,C语言,char,内存,对齐
From: https://www.cnblogs.com/liumy/p/17092840.html

相关文章

  • C语言学习 结构体
    定义一个结构体 structCompany{char*name;char*id;char*location;}初始化1structCompanycompany={.name="imooc",.id="1212121"};怎么省略st......
  • 06 创建对象内存分析
    现在不太懂什么是栈,什么是堆?无关代码,个人此时喜好记录packagecom.zhan.base05Oop;publicclassTest06{publicstaticvoidmain(String[]args){P......
  • Go应用服务疑似内存泄露问题排查
    背景为了保障业务的可用性,增加应用服务请求依赖服务(grpc、http)的熔断降级策略,避免依赖服务不可用的情况下,出现级联服务故障产生雪崩,通过熔断降级尽可能把影响缩放到最小。因......
  • 论文阅读: CCF A(ICSE) 2022 MVD: 基于流敏感图神经网络的内存相关漏洞检测
    Abstract:内存相关漏洞对现代软件的安全构成了严重威胁。尽管基于深度学习的方法在一般性漏洞检测方面取得了成功,但在应用于内存相关漏洞检测时,仍然受到流信息利用不......
  • 【C语言】为什么使用文件、什么是文件、文件名、文件指针。
    ......
  • 使用c语言完成简单的三子棋
    完成一个三子棋项目首先我们要知道要学会对头文件和不同源文件功能的划分首先创建一个头文件两个源文件如图其中我们将所有要引用函数的头文件放入头文件.h中主逻辑里面放的......
  • 用指针来输出字符串元素的个数--C语言
    现在的状态就是,心里很空虚,感觉干啥都不得意,学东西学不进去,玩也玩不好,但是现实告诉我一定要想办法升华自己intmy_strlen(char*str){char*start=str;char*end=str......
  • 一次因内存引用引发的数据重复的问题
    前言第一次使用expandablelistview,其中要创建一个二维的arraylist,但在使用过程中导致一直出现数据重复的状况,入图所示当独立打开一组并关闭其他组时,显示正常。但当打开......
  • 初识C语言3
       今天学习了原码补码反码之间的关系、昨天没学完的操作符、关键字、如何产生地址。   正数是原码反码补码三码统一,负数在计算机以补码的形式存储,而打印出来的是......
  • C语言初阶思维导图
    ​​C语言初阶思维导图文字版​​​​C语言思维导图清晰版​​......