转自:http://www.cnblogs.com/JensenCat/p/4770171.html

这里是头文件结构的定义:

一个非字节对齐结构体_tagTest2

一个字节对齐_tagTest3

(使用#pragma pack(push,1)来使字节以1个来对齐 , 使用#pragma pack(pop)来还原默认)

  1. #pragma once
  2.  
  3. struct _tagTest1
  4. {
  5. };
  6.  
  7. //非字节对齐的结果
  8. struct _tagTest2
  9. {
  10. int n1;
  11. char ch1;
  12. float f1;
  13. char szName[];
  14. _tagTest1* pTag;
  15. };
  16.  
  17. #pragma pack(push,1)
  18. //_tagTest3和2是一样的结构,字节对齐后的结果
  19. struct _tagTest3
  20. {
  21. int n1;
  22. char ch1;
  23. float f1;
  24. char szName[];
  25. _tagTest1* pTag;
  26. };
  27.  
  28. #pragma pack(pop)

这里是实验代码:注释处写了分析,结果也入分析所料

  1. #include "msgdef.h"
  2. #include <Windows.h>
  3. #include <iostream>
  4. using namespace std;
  5.  
  6. void main()
  7. {
  8. /*
  9. 非字节对齐下,当前最大的空间是4个字节,所有结构都会向4个字节对齐...
  10. int n1; 4
  11. char ch1; 4 注解:1不是4的倍数..将扩张到4
  12. float f1; 4
  13. char szName[21]; 24 注解:21不是4的倍数..将扩张到24
  14. _tagTest1* pTag; 4
  15. 总和为:40
  16. */
  17. _tagTest2 k2;
  18. cout<<"size of _tagTest2: "<<sizeof(k2)<<endl;
  19. //看看内存模型
  20. k2.n1 = ;
  21. k2.ch1 = ;
  22. k2.f1 = 1.0f;
  23. memset(k2.szName , , sizeof(k2.szName));
  24. k2.pTag = (_tagTest1*)&k2.n1; //此处测试用,别纠结
  25.  
  26. /*
  27. 字节对齐下,
  28. int n1; 4
  29. char ch1; 1
  30. float f1; 4
  31. char szName[21]; 21
  32. _tagTest1* pTag; 4
  33. 总和为:34
  34. */
  35. _tagTest3 k3;
  36. cout<<"size of _tagTest3: "<<sizeof(k3)<<endl;
  37. //看看内存模型
  38. k3.n1 = ;
  39. k3.ch1 = ;
  40. k3.f1 = 1.0f;
  41. memset(k3.szName , , sizeof(k3.szName));
  42. k3.pTag = (_tagTest1*)&k3.n1; //此处测试用,别纠结
  43.  
  44. system("pause");
  45. }

实验结果输出:如分析所说的一样

这时候问题来了,那么字节不对齐时在内存是怎样的呢...下面是字节不对齐时的内存截图

下面的顺序清楚的对应,其中字节对齐的空位在内存里面补了cc,这个为什么本人没有深究,其他变量一目了然了,

至于浮点数的内存模型为什么是这样,可以度娘一下,很多人分析了浮点数float的内存模型。

----------------------------------------------------------------------------------------------------------------------------

----------------------------邪恶的分割线------------------------------------------------------------------------------------

2.0版本:

鉴于上面有些地方不够清晰...现在再列出几个例子...例子来自网上摘下...

1.在不对齐的情况下,拥有相同变量的结构最后得出的size也是不一样的..

  1. //定义两个结构,下面描述一下内存存放地址
  2. struct A
  3. {
  4. //假设内存地址从0开始...
  5. int a; //0-3
  6. char b; //4
  7. short c;//6-7
  8. }
  9. //由于0-7的相加的结果为8...为自对齐4的倍数...
  10. //所以结果:sizeof(A) = 8
  11.  
  12. //
  13. struct B
  14. {
  15. //假设内存地址从0开始...
  16. char a;//0
  17. int b; //4-7
  18. short c;//8-10
  19. }
  20. //由于0-10的相加的结果为11...不为自对齐4的倍数...补齐后为12
  21. //所以结果:sizeof(B) = 12

2.再来使用Pragma手工更改了字节对齐值的情况,先看看Struct C的定义:

  1. #pragma pack(2)
  2. struct C
  3. {
  4. //假设从0开始
  5. char a;//0
  6. int b;//2-5
  7. short c;//6-7
  8. };
  9. sizeof(C)的答案为8

Struct C的分析摘自网友总结:

step 1: 确定结构体C对齐值:选择成员中最大的对齐值,即int a,对齐值为4       

step 2: 确定手工指定对齐值,使用手工指定的值:2

step 3: char a 的有效地址值=min(1,2),(因为0x0000%2=0),这样a的地址就是0x0000 

step 4: int b 的有效对齐值=min(4,2),地址依次从0x0002~0x0005 (因为Ox0002%2=0)开始,分配4个字节,目前地址段分配情况就是:0x0000~0x0005    

step 5: short c 的有效对齐值=min(2,2),由于要求考虑到对齐的情况,从0x0006(因为0x0006%2=0)开始,分配2个字节的地址0x0006~0x0007

目前为止,地址段的分配情况就是:0x0000~0x0007共8个字节,同时也保证了Struct C的对齐情况(2字节对齐,pragma(2)),sizeof(C)=8

结论:

最后的最后补多一个混合的例子:

  1. struct tagS1
  2. {
  3. //假设地址从0开始,这里最长的类型为_unT1,长度为8...
  4. //变量的首地址为地址模sizeof(变量类型)结果为0的地址开始
  5. char a;//0 (0模1==0,所以从0开始)
  6. int n;//4-7 (2和3模4不等于0,从4开始)
  7. _unT1 t1;//8-15(8模8等于0,从8开始)
  8. long l;//16-19(16模4等于0,从16开始)
  9. char sz[];//20-41(20模1等于0,从20开始)
  10. };
  11. //由于0-41的长度为42,42不为8的倍数,所以补长为8的倍数,结果为48

C++结构体字节对齐的更多相关文章

  1. [置顶] 什么是C语言结构体字节对齐,为什么要对齐?

    一.概念 对齐跟数据在内存中的位置有关.如果一个变量的内存地址正好位于它长度的整数倍,他就被称做自然对齐.比如在32位cpu下,假设一个整型变量的地址为0x00000004,那它就是自然对齐的.   ...

  2. C/C++结构体字节对齐详解

    结构体的sizeof先看一个结构体:struct S1{    char c;    int i;}; sizeof(S1)在VC6中按默认设置得到的结果为8.我们先看看sizeof的定义——size ...

  3. C语言 结构体字节对齐问题

    摘选自这位大神的博客 方法一: 结构体在内存中分配一块连续的内存,但结构体内的变量并不一定是连续存放的,这涉及到内存对齐. 原则1  数据成员对齐规则:结构(struct或联合union)的数据成员, ...

  4. C/C++ 结构体字节对齐

    在用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题.从理论上讲,对于任何 变量的访问都可以从任何地址开始访问,但是事实上不是如此 ...

  5. 【c++】【转】结构体字节对齐

    http://www.cnblogs.com/heyonggang/archive/2012/12/11/2812304.html

  6. C语言结构体的对齐原则

    Q:关于结构体的对齐,到底遵循什么原则?A:首先先不讨论结构体按多少字节对齐,先看看只以1字节对齐的情况: #include <stdio.h> #include <string.h ...

  7. C语言 结构体(联合体)对齐规则

    /* 结构体(联合体)对齐规则 */ #include <stdio.h> #include <stdlib.h> #include <string.h> /* * ...

  8. c中结构体边界对齐

    原则1.普通数据成员对齐规则:第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储). 原则2 ...

  9. 再谈:自定义结构体的对齐问题之__attribute__ ((packed))方法【转】

    转自:https://blog.csdn.net/ipromiseu/article/details/5955295 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.c ...

随机推荐

  1. QrenCode : 命令行下生成二维码图片

    对于二维码大家应该并不陌生,英文名为 2-dimensional bar code 或 QR Code,是一种用图形记载信息的技术,最常见的是应用在手机应用上.用户通过手机摄像头扫描二维码或输入二维码 ...

  2. ASP.NET MVC中ViewBag和ViewData的区别

    在MVC3.0以上我们会用到ViewBag或者ViewData进行页面传值,对比一下二者的差距: ViewData ViewBag 基于key/value的字典集合 dynamic类型对象 从ASP. ...

  3. 【转】C#中的Stream

    C# 温故而知新:Stream篇(—) C# 温故而知新:Stream篇(二) C# 温故而知新:Stream篇(三) C# 温故而知新:Stream篇 (四) C# 温故而知新:Stream篇(五) ...

  4. hihocoder 1305 - 区间求差 - [hiho一下152周][区间问题]

    题目链接:https://hihocoder.com/problemset/problem/1305 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定两个区间集合 A ...

  5. django比较相等或者不相等的模板语法ifequal / ifnotequal

    转自:http://blog.csdn.net/goupper1991/article/details/50768346 ifequal / ifnotequal      在模板语言里比较两个值并且 ...

  6. ECharts修改坐标轴,坐标轴字体,坐标轴网格样式以及控制坐标轴是否显示

    转自:http://blog.csdn.net/kirinlau/article/details/72876689 首先要将一个图表显示在前端页面上: var myChart = echarts.in ...

  7. 新购买的vps应该做的几件事情

    1. 修改root密码      passwd   root 2.新建用户     useradd  vinentguo 3.配置免密码登陆 .使用新建用户登陆vps. mkdir ~/.ssh/ch ...

  8. arcgis api for JavaScript _跨域请求

    arcgis api for JavaScript  中出现跨域请求是常见问题, 通常出现类似如下错误消息类似: XMLHttpRequest cannot load http://10.32.2.7 ...

  9. Linux下Miniconda量化环境安装

    前言 linux目录相关知识 /usr:系统级的目录,可以理解为C:/Windows/,/usr/lib理解为C:/Windows/System32./usr/local:用户级的程序目录,可以理解为 ...

  10. HTML文件默认内容

    <!DOCTYPE html> <!-- 声明使用html5标准 --> <html lang="en"> <!-- html标签开始(只 ...