zoukankan      html  css  js  c++  java
  • C/C++中sizeof的详细测试分析报告

    以下数据来自于Dev CPP

    首先呈现实际测试数据:

    主程序如下:

     1 #include <string.h>
     2 #include <iostream>
     3 
     4 using namespace std;
     5 
     6 typedef struct s1 {
     7 //char ch, *ptr;
     8 union {
     9 short a, b;
    10 //unsigned int c:2, d:1;
    11     };
    12 };
    13 //struct s1 *next;
    14 //};
    15 
    16 int main()
    17 {
    18     printf("%d\n",sizeof(s1));
    19     system("pause");
    20     return 1;
    21 }

    下面的测试数据,通过不断修改struct的结构体内容,来达到不同的测试结果。

    1 typedef struct s1 {
    2 //char ch, *ptr;
    3 union {
    4 short a, b;
    5 //unsigned int c:2, d:1;
    6     };
    7 };

    以上测试样例一输出答案:2

    1 typedef struct s1 {
    2 char ch, *ptr;
    3 //union {
    4 //short a, b;
    5 //unsigned int c:2, d:1;
    6 //    };
    7 };

    以上测试样例二输出答案:8

    1 typedef struct s1 {
    2 char ch;//, *ptr;
    3 //union {
    4 //short a, b;
    5 //unsigned int c:2, d:1;
    6 //    };
    7 };

    以上测试样例三输出答案:1

    1 typedef struct s1 {
    2 char ch, *ptr;
    3 union {
    4 //short a, b;
    5 //unsigned int c:2, d:1;
    6 };
    7 };

    以上测试样例四输出结果:12

    1 typedef struct s1 {
    2 char ch, *ptr;
    3 union {
    4 short a, b;
    5 //unsigned int c:2, d:1;
    6     };
    7 };

    以上测试样例五输出答案:12

    1 typedef struct s1 {
    2 char ch, *ptr;
    3 union {
    4 short a, b;
    5 unsigned int c:2, d:1;
    6     };
    7 };

    以上测试样例六输出答案:12

    1 typedef struct s1 {
    2 //char ch, *ptr;
    3 union {
    4 short a, b;
    5 unsigned int c:2, d:1;
    6     };
    7 };

    以上测试样例七输出答案:4

    1 typedef struct s1 {
    2 //char ch, *ptr;
    3 union {
    4 //short a, b;
    5 unsigned int c:2, d:1;
    6     };
    7 };

    以上测试样例八输出答案:4

    1 typedef struct s1 {
    2 //char ch, *ptr;
    3 union {
    4 //short a, b;
    5 //unsigned int c:2, d:1;
    6     };
    7 };

    以上测试样例九输出答案:1

    通过上述实验结果而知,首先对于32bits的PC来说,定义下:

    char,uchar 1个字节

    int uint 4个字节

    union一个字节

    上述是前提,供后续分析使用。

    首先是字节对齐的问题,何为字节对齐?

    个人认为字节对齐主要是因为两个方面的原因:

    1. 统一标准,进行不同设备间的通讯,比如:异构CPU,异构内存模型等等
    2. 加速数据的访问,字节对齐能使得取值,save等操作更加方便,因为存储时起始地址都是对齐后的地址。

    那么非结构体时,无需考虑sizeof后的效果,因为原生态的类型,在存储时占用大小一致,只是原生态的变量间会有不同的填充空间。

    下面只是分析结构体内的处理方式,下面是几个原则:

    1. 结构体对齐存在结构体内对齐,结构体对齐两个部分。
    2. 结构体内每个变量存放的其实地址必须是自己所用大小的整数倍。
    3. 结构体对齐需要结构体的长度是结构体内最大占用变量的长度的整数倍。
    4. union占用一个字节,内部变量共享所有的内存。

    下面利用上述三个原则来重新分析下上述实验结果。

    1 typedef struct s1 {
    2 //char ch, *ptr;
    3 union {
    4 short a, b;
    5 //unsigned int c:2, d:1;
    6 };
    7 };

    以上测试样例一输出答案:2

    union共享内存,也就是说a b两个变量共享内存,short在32bits机器中是双字节变量,所以长度为2;

    结构体对齐:目前内部长度是2,内部最大变量也是2,所以是整数倍。不需要结构体对齐。最终结果是2;

    1 typedef struct s1 {
    2 char ch, *ptr;
    3 //union {
    4 //short a, b;
    5 //unsigned int c:2, d:1;
    6 // };
    7 };

    以上测试样例二输出答案:8

    结构体内有两个变量,char char*

    首先char型占用一个字节,char*指针占用四个字节。

    指针需要从addr%4==0的地址开始,所以char---char*之间系统需要补充3个字节。

    所以char+char*后的长度是8,最长的内部变量长度是char*=4个,所以满足结构体对齐,不需要结构体调整。

    所以最终长度是8。

    1 typedef struct s1 {
    2 char ch;//, *ptr;
    3 //union {
    4 //short a, b;
    5 //unsigned int c:2, d:1;
    6 // };
    7 };

    以上测试样例三输出答案:1

    简单的char是1个字节,结构体内长度=1,最长变量长度也是1,所以满足条件,无需结构体调整。

    1 typedef struct s1 {
    2 char ch, *ptr;
    3 union {
    4 //short a, b;
    5 //unsigned int c:2, d:1;
    6 };
    7 };

    以上测试样例四输出结果:12

    char+char*后的长度是8,union长度默认是1,

    所以长度应该是9,但是结构体内最大变量的长度是4,不满足addr%4==0,所以结构需要进行调整。

    (9+x)%4==0的最小长度是12

    所以程序输出为12;

    1 typedef struct s1 {
    2 char ch, *ptr;
    3 union {
    4 short a, b;
    5 //unsigned int c:2, d:1;
    6 };
    7 };

    以上测试样例五输出答案:12

    char====1

    填充====3个空白字节

    char*===4

    union====1(内部short===2,a b共用2个字节),所以union长度是max(union,short)==2;

    结构体内长度:1+3+4+2=10;

    不满足结构体长度%4==0;

    所以需要进行调整,最终为12

    1 typedef struct s1 {
    2 char ch, *ptr;
    3 union {
    4 short a, b;
    5 unsigned int c:2, d:1;
    6 };
    7 };

    以上测试样例六输出答案:12

    这个分析同上。

    只是需要说明的是位域在union中也是当成一个单独的变量,共用最长变量的内存单元,unsigned int长度为4。

    1 typedef struct s1 {
    2 //char ch, *ptr;
    3 union {
    4 short a, b;
    5 unsigned int c:2, d:1;
    6 };
    7 };

    以上测试样例七输出答案:4

    同上

    1 typedef struct s1 {
    2 //char ch, *ptr;
    3 union {
    4 //short a, b;
    5 unsigned int c:2, d:1;
    6 };
    7 };

    以上测试样例八输出答案:4

    同上

    1 typedef struct s1 {
    2 //char ch, *ptr;
    3 union {
    4 //short a, b;
    5 //unsigned int c:2, d:1;
    6 };
    7 };

    以上测试样例九输出答案:1

    原则性的条款,union默认长度是byte长度===1

    作者:W.M.steve
    出处:http://www.cnblogs.com/weisteve/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    Opengl编程指南第三章:视图
    OpenGL编程指南第四章:颜色
    OpenGL编程指南第七章:显示列表
    推荐:字体、排版简明入门
    OpenGL编程指南第八章:绘制像素、位图、字体和图像
    推荐:字体、排版简明入门
    OpenGL编程指南第五章:光照
    转载一篇密码学基本介绍
    ARM_异常和中断学习笔记
    ARM指令学习笔记
  • 原文地址:https://www.cnblogs.com/weisteve/p/2200269.html
Copyright © 2011-2022 走看看