C++结构体字节对齐
转自:http://www.cnblogs.com/JensenCat/p/4770171.html
这里是头文件结构的定义:
一个非字节对齐结构体_tagTest2
一个字节对齐_tagTest3
(使用#pragma pack(push,1)来使字节以1个来对齐 , 使用#pragma pack(pop)来还原默认)
#pragma once struct _tagTest1
{
}; //非字节对齐的结果
struct _tagTest2
{
int n1;
char ch1;
float f1;
char szName[];
_tagTest1* pTag;
}; #pragma pack(push,1)
//_tagTest3和2是一样的结构,字节对齐后的结果
struct _tagTest3
{
int n1;
char ch1;
float f1;
char szName[];
_tagTest1* pTag;
}; #pragma pack(pop)
这里是实验代码:注释处写了分析,结果也入分析所料
#include "msgdef.h"
#include <Windows.h>
#include <iostream>
using namespace std; void main()
{
/*
非字节对齐下,当前最大的空间是4个字节,所有结构都会向4个字节对齐...
int n1; 4
char ch1; 4 注解:1不是4的倍数..将扩张到4
float f1; 4
char szName[21]; 24 注解:21不是4的倍数..将扩张到24
_tagTest1* pTag; 4
总和为:40
*/
_tagTest2 k2;
cout<<"size of _tagTest2: "<<sizeof(k2)<<endl;
//看看内存模型
k2.n1 = ;
k2.ch1 = ;
k2.f1 = 1.0f;
memset(k2.szName , , sizeof(k2.szName));
k2.pTag = (_tagTest1*)&k2.n1; //此处测试用,别纠结 /*
字节对齐下,
int n1; 4
char ch1; 1
float f1; 4
char szName[21]; 21
_tagTest1* pTag; 4
总和为:34
*/
_tagTest3 k3;
cout<<"size of _tagTest3: "<<sizeof(k3)<<endl;
//看看内存模型
k3.n1 = ;
k3.ch1 = ;
k3.f1 = 1.0f;
memset(k3.szName , , sizeof(k3.szName));
k3.pTag = (_tagTest1*)&k3.n1; //此处测试用,别纠结 system("pause");
}
实验结果输出:如分析所说的一样

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

下面的顺序清楚的对应,其中字节对齐的空位在内存里面补了cc,这个为什么本人没有深究,其他变量一目了然了,
至于浮点数的内存模型为什么是这样,可以度娘一下,很多人分析了浮点数float的内存模型。
----------------------------------------------------------------------------------------------------------------------------
----------------------------邪恶的分割线------------------------------------------------------------------------------------
2.0版本:
鉴于上面有些地方不够清晰...现在再列出几个例子...例子来自网上摘下...
1.在不对齐的情况下,拥有相同变量的结构最后得出的size也是不一样的..
//定义两个结构,下面描述一下内存存放地址
struct A
{
//假设内存地址从0开始...
int a; //0-3
char b; //4
short c;//6-7
}
//由于0-7的相加的结果为8...为自对齐4的倍数...
//所以结果:sizeof(A) = 8 //
struct B
{
//假设内存地址从0开始...
char a;//0
int b; //4-7
short c;//8-10
}
//由于0-10的相加的结果为11...不为自对齐4的倍数...补齐后为12
//所以结果:sizeof(B) = 12
2.再来使用Pragma手工更改了字节对齐值的情况,先看看Struct C的定义:
#pragma pack(2)
struct C
{
//假设从0开始
char a;//0
int b;//2-5
short c;//6-7
};
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
结论:

最后的最后补多一个混合的例子:
struct tagS1
{
//假设地址从0开始,这里最长的类型为_unT1,长度为8...
//变量的首地址为地址模sizeof(变量类型)结果为0的地址开始
char a;//0 (0模1==0,所以从0开始)
int n;//4-7 (2和3模4不等于0,从4开始)
_unT1 t1;//8-15(8模8等于0,从8开始)
long l;//16-19(16模4等于0,从16开始)
char sz[];//20-41(20模1等于0,从20开始)
};
//由于0-41的长度为42,42不为8的倍数,所以补长为8的倍数,结果为48
C++结构体字节对齐的更多相关文章
- [置顶]
什么是C语言结构体字节对齐,为什么要对齐?
一.概念 对齐跟数据在内存中的位置有关.如果一个变量的内存地址正好位于它长度的整数倍,他就被称做自然对齐.比如在32位cpu下,假设一个整型变量的地址为0x00000004,那它就是自然对齐的. ...
- C/C++结构体字节对齐详解
结构体的sizeof先看一个结构体:struct S1{ char c; int i;}; sizeof(S1)在VC6中按默认设置得到的结果为8.我们先看看sizeof的定义——size ...
- C语言 结构体字节对齐问题
摘选自这位大神的博客 方法一: 结构体在内存中分配一块连续的内存,但结构体内的变量并不一定是连续存放的,这涉及到内存对齐. 原则1 数据成员对齐规则:结构(struct或联合union)的数据成员, ...
- C/C++ 结构体字节对齐
在用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题.从理论上讲,对于任何 变量的访问都可以从任何地址开始访问,但是事实上不是如此 ...
- 【c++】【转】结构体字节对齐
http://www.cnblogs.com/heyonggang/archive/2012/12/11/2812304.html
- C语言结构体的对齐原则
Q:关于结构体的对齐,到底遵循什么原则?A:首先先不讨论结构体按多少字节对齐,先看看只以1字节对齐的情况: #include <stdio.h> #include <string.h ...
- C语言 结构体(联合体)对齐规则
/* 结构体(联合体)对齐规则 */ #include <stdio.h> #include <stdlib.h> #include <string.h> /* * ...
- c中结构体边界对齐
原则1.普通数据成员对齐规则:第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储). 原则2 ...
- 再谈:自定义结构体的对齐问题之__attribute__ ((packed))方法【转】
转自:https://blog.csdn.net/ipromiseu/article/details/5955295 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.c ...
随机推荐
- POJ-2336 Ferry Loading II(简单DP)
Ferry Loading II Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3763 Accepted: 1919 Desc ...
- poj3614 Sunscreen【贪心】
Sunscreen Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11772 Accepted: 4143 Descri ...
- poj1696 Space Ant【计算几何】
含极角序排序模板. Space Ant Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5334 Accepted: ...
- MPD大会北京上海两站圆满落幕
MPD大会北京上海两站圆满落幕 由麦思博(MSUP)主办的亚太软件研发团队管理峰会(以下简称MPD大会)分别于6月15及6月22日在北京.上海成功举办.国内外知名软件.互联网行业项目领头人及业内从业人 ...
- mysql全局唯一ID生成方案(二)
MySQL数据表结构中,一般情况下,都会定义一个具有‘AUTO_INCREMENT’扩展属性的‘ID’字段,以确保数据表的每一条记录都可以用这个ID唯一确定: 随着数据的不断扩张,为了提高数据库查询性 ...
- 网卡配置/etc/network/interfaces
话说Debian系的网卡配置跟Redhat系很不一样,Redhat是放在/etc/sysconfig/network-scripts目录下面的一大堆文件里面,要修改?你一个一个文件来过吧.Debian ...
- oracle动态视图(一)stat
1v$mystat,v$sesstat,v$sysstat是用来分别统计用户级,会话级,系统级信息的. SID NUMBER STATI ...
- Python第三方库官网
Python第三方库官网 https://pypi.python.org/pypi 包下载后的处理: 下载后放到Python的scripts文件夹中(D:\Python3.5\Scripts),用cm ...
- xls的读写
import xlrd # 读取xls文件 # 打开xls文件 data = xlrd.open_workbook('x1.xls') print(type(data)) # 获取表Sheet1 ta ...
- 10 ref 和 out 之间的差别
(1) 两者都是按地址传递的,使用后都将改变原来的数值 (2) ref传进去的參数必须在调用前初始化,out不必 (3) ref传进去的參数在函数内部能够直接使用,而out不可 (4) ref传进去的 ...