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 ...
随机推荐
- &与&&, |与||区别
&和|称为短逻辑符,&&及||称为长逻辑符.长逻辑符只比较左边和右边的第一个元素,而短逻辑符会比较所有的 > a<-c(TRUE, FALSE, TRUE, FAL ...
- HDFS体系结构(NameNode、DataNode详解)
hadoop项目地址:http://hadoop.apache.org/ NameNode.DataNode详解 (一)分布式文件系统概述 数据量越来越多,在一个操作系统管辖的范围存不下了,那么就分配 ...
- Mapreduce 原理及程序分析
1.MapReduce(Map+Reduce) 提出一个问题: 目标:你想数出一摞牌中有多少张黑桃. 直观方式:一张一张检查并且数出有多少张是黑桃数目 MapReduce方法则是: 给在座的所有玩家中 ...
- 计蒜客 31453 - Hard to prepare - [递归][2018ICPC徐州网络预赛A题]
题目链接:https://nanti.jisuanke.com/t/31453 After Incident, a feast is usually held in Hakurei Shrine. T ...
- 实例Python处理XML文件的方法
转自:http://www.jb51.net/article/71773.htm 以下是部分代码: <?xml version="1.0" encoding="UT ...
- paas容器云
- MYSQL中的CASE WHEN END AS
SELECT id,`NAME`,province,city, phone, CASE sex WHEN 'M' THEN '男' WHEN 'F' THEN '女'END AS sexFROM `p ...
- 前端 HTML的规范
1.编写HTML规范 1)所有标记元素都要正确的嵌套,不能交叉嵌套.正确写法举例:<h1><font></font></h1> (2)HTML标签通常是 ...
- read 命令
read 用来接收标准输入 #!/bin/bash read -t -p "Please input a number:" number echo $number //把键盘输入的 ...
- [javascript]编码&i字符串格式化&nput历史记录&清空模态框
js中编码问题 https://www.haorooms.com/post/js_escape_encodeURIComponent 我在前端js添加时候创建dom时候,有汉字,发现是乱码就研究了下 ...