zoukankan      html  css  js  c++  java
  • C语言学习笔记_结构体的内存对齐

    C语言学习笔记_结构体的内存对齐

    结构体的指针访问和下标访问

    结构体可以在定义的同时申明变量:

    // 定义的同时申明变量s1;
    struct student {
    	int a;
    	double b;
        char c;
    }s1 ;
    // 申明s2;
    struct student s2;
    

    结构体的下标访问:

    s1.a = 1;
    s1.b = 2.2;
    s1.c = 'x';
    
    printf("s1.a = %d.
    ", s1.a);
    printf("s1.a = %f.
    ", s1.b;
    printf("s1.a = %c.
    ", s1.c);
    

    结构体的指针访问:

    // 第一个变量在开始,所以直接转换结构体的地址为int *;
    int *p = (int *)&s1; 
    *p = 12;
    printf("s1.a = %d.
    ", s1.a);
    
    // 经过第一个变量到达第二个变量的首地址,第一个变量为int,所以转换为int类型在加4,得到真正的地址;
    double *d = (double *)((int)&s1+4); 
    *d = 3.3;
    printf("s1.a = %f.
    ", s1.b;
    
    // 和上一个相同,不过double类型的长度为8,所以地址相差4+8=12;    
    char *c = (char *)((int)&s1+12);
    *c = 'y';
    printf("s1.a = %c.
    ", s1.c);
    

    可以发现结构体的指针访问可以更好的理解结构体的对齐访问;

    结构体的对齐访问

    结构体中的数据类型长短不一,数据的对齐访问方式牺牲部分内存以提高访问效率,;

    在32位系统中采用4字节对齐,有以下特点:

    1. 结构体本身必须在4字节对齐处;
    2. 结构体对齐后的大小必须是4的倍数,N字节对齐则为N的整数倍;
    3. 结构体中每个元素必须对齐存放,每个元素有自身的对齐规则;
    4. 编译器考虑结构体存放时,以满足以上规则的最少内存消耗策略;

    下面是一些对齐访问的案例

    struct s1 {         // 无对齐     4字节对齐
    	int a;          // 4         4		  
    	char b;         // 1         2(1+1)
    	short c;        // 2         2
    };                  
    sizeof(struct s1);  // 7         8
    
    struct s2 {         // 无对齐     4字节对齐
        char a;         // 1         4(1+3)
        int b;          // 4         4
        short c;        // 2         4(2+2)
    };                  
    sizeof(struct s2);  // 7         12
    
    struct s3 {         // 无对齐     4字节对齐
        int a;          // 4         4
        struct s1 s;    // 7         8
        double b;       // 8         8
        int c;          // 4         4
    };                  
    sizeof(struct s3);  // 23        24
    
    struct student{     // 无对齐     4字节对齐
        char sex;       // 1         4(1+3)
        int length;     // 4         4
        char name[10];  // 10        12(10+2)
    };                  
    sizeof(struct student);// 15        20 
    

    gcc的对齐指令

    gcc支持但不推荐的对齐指令:

    通过pramaga指令和参数k设置一个区间,此区间内为k字节对齐:

    // 设置对齐字节为1字节,相当于不对齐
    #pragma pack(1)
    struct s1 {         
    	int a;          	  
    	char b;         
    	short c;        
    };                  
    // 长度为7
    printf("sizeof(struct s1) = %d.
    ", sizeof(struct s1)); 
    
    // 结束
    #pragma pack
    

    gcc支持且推荐的对齐指令:

    在声明结构体的后面加上该指令,只作用于此类型;

    //  __attribute__((packed))表示取消对齐,只作用于s1;
    struct s1 {         
    	int a;          	  
    	char b;         
    	short c;        
    } __attribute__((packed)); 
    
    // __attribute__((aligned(n)))表示结构体设置整体n个字节对齐,这里设置4字节对齐,只作用于s2;
    struct s2 {         
    	int a;          	  
    	char b;         
    	short c;        
    } __attribute__((aligned(4))); 
    

    注意这里的aligned是整体n字节对齐,和前面的对齐以及prama的对齐不一样,前面的对齐是结构体中每个元素按照n字节对齐,而aligned中结构体的元素还是4字节对齐,整体按照n字节对齐;

  • 相关阅读:
    ZOJ 1002 Fire Net (火力网)
    UVa OJ 117 The Postal Worker Rings Once (让邮差只走一圈)
    UVa OJ 118 Mutant Flatworld Explorers (变体扁平世界探索器)
    UVa OJ 103 Stacking Boxes (嵌套盒子)
    UVa OJ 110 MetaLoopless Sorts (无循环元排序)
    第一次遇到使用NSNull的场景
    NSURL使用浅析
    从CNTV下载《小小智慧树》
    NSDictionary and NSMutableDictionary
    Category in static library
  • 原文地址:https://www.cnblogs.com/sakurapiggy/p/13200130.html
Copyright © 2011-2022 走看看