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-2029 Get Many Persimmon Trees(动态规划)
Get Many Persimmon Trees Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 3987 Accepted: 2 ...
- Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2)---ABC
A---The King's Race http://codeforces.com/contest/1075/problem/A 题意: 一个人在\((1,1)\), 一个人在\((n,n)\), 现 ...
- JSON.stringify() 格式化 输出log
调试程序的过程中,我们打印一个日志: console.log(object);,其中object是任意的一个json对象. 在控制台就会看到[object object],而看不到具体的内容. 我们可 ...
- 教程 | 如何使用纯NumPy代码从头实现简单的卷积神经网络
Building Convolutional Neural Network using NumPy from Scratch https://www.linkedin.com/pulse/buildi ...
- 【python+opencv】直线检测+圆检测
Python+OpenCV图像处理—— 直线检测 直线检测理论知识: 1.霍夫变换(Hough Transform) 霍夫变换是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛,也有很多改进 ...
- BPDU报文(RSTP)
与STP 的BPDU报文格式相同,就是在flags字段报文中间几位得到应用 主要原理:利用flages位中的Proposal与Agreement来进行协商,从而快速从 discarding 转成 fo ...
- [解决]WPF 在 win7 系统无法运行:FileNotFoundException
开发环境:VS2015 + .NET 4.6.2 开发项目1:WPF + CefSharp 开发项目2:WPF 情况:两个项目编译的程序都无法在客户环境的 win7上运行,事件查看器中如下日志: Th ...
- 3.对神经网络训练中Epoch的理解
代表的是迭代的次数,如果过少会欠拟合,反之过多会过拟合 EPOCHS 当一个完整的数据集通过了神经网络一次并且返回了一次,这个过程称为一个 epoch. 然而,当一个 epoch 对于计算机而言太 ...
- js 的each()方法遍历对象和数组
<script src="../lib/jquery-1.8.3.min.js" ></script> <script type="text ...
- [django]Django model中数据批量导入bulk_create()
参考: https://www.cnblogs.com/ccorz/p/Django-model-zhong-shu-ju-pi-liang-dao-rubulkcreat.html import o ...