关于结构体中的内存空洞、sizeof(struct)以及编译器优化的见解

#include

struct node
{
 

   int num;               //4
    char name[20];   //20
    char sex  ;        //1
    int age;               //4        
    float score;    //4            
    char add[30];      //30            
};

int main()
{
    struct node p;
    printf("%d",sizeof(p));
    printf("\n************\n");
    printf("%d\n",sizeof(float));
    return 0;
}
/*
  内存地址要对齐。。
  结构体每个保存都是按照最长的定义类型来的。

  字节对齐的细节和编译器实现相关,但一般而言,满足三个准则:
  1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
  2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是最宽基本类型成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
  3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。

比如上面最长的是int和float 都是4个字节

见下示例图。
口口口口            int  num                   4字节


口口口口
口口口口
口口口口            char names[20]             20字节
口口口口
口口口口            



口X X X             char sex                    4字节           有3字节的内存空洞


口口口口            int age                     4字节


口口口口            float score                 4字节


口口口口   
口口口口
口口口口
口口口口
口口口口            char add[30]                32字节           2字节的内存空洞
口口口口
口口口口
口口X X

运行的结果与分析一致
关于结构体中的内存空洞和编译器 <wbr>的优化

之前在谭浩强的书上看到了关于结构体的sizeof,然后自己 在 查看资料的时候看到了内存空洞这个概念,再加之后来在梁哥的课上曾经讲过这个,但只是提到了int和short的对齐,其他的并没有提到。今天再书上又看到了这个类型 的,谭老先生的编译工具是TC,TC没有用过,所以我不敢断然否定。

另外关于编译器的优化

举个例子吧。
#include

struct node
{
    int a;
    char b;
    char c;
    short d;
         
};

int main()
{
    struct node p;
    printf("%d",sizeof(p));
    printf("\n************\n");
    return 0;
}
还是用同样的方法:
口口口口        int a
口口口口        char b,c;short d;
sizeof(p)的大小是8而不是12
主要因为是一个整形的字节的内存可以正好存放2个char型和1个short型的变量
运行结果 :关于结构体中的内存空洞和编译器 <wbr>的优化

但是如果定义变量的时候是 这样 定义的
    int a;
    char b;
    int c;
    char d;
sizeof(p)的结果就为16
关于结构体中的内存空洞和编译器 <wbr>的优化

所以在结构中定义变量的时候要 把内存空洞这个考虑进去,避免不必要 的内存浪费。毕竟编译器是还是没有人灵活的。
posted @ 2013-04-16 21:55  菜鸟上路ING  阅读(1039)  评论(1编辑  收藏  举报