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 ...
随机推荐
- Spring Framework框架容器核心源码逐步剖析
目录 构建Spring环境 Spring 版本 5.1.3.RELEASE 测试类 Spring 配置文件 测试方法Main 快速进入Debug查看IOC容器构建源码 Spring IOC源码步骤分析 ...
- ELK之使用filebeat的多行过滤插件把多行合并成一行
java运行日志一般有多行,格式类似如下 格式为:日期 + 日志级别 + 日志信息 有些日志是多行的,需要使用filebeat多行插件把多行合并成一行 未使用多行插件的日志格式 修改filebeat配 ...
- ubuntu下安装opencv3.1.0
ubuntu14.04安装opencv3.1 1.下载opencv3.1源码http://opencv.org/releases.html 2.安装opencv3 2.1安装opencv3的依赖 1 ...
- Gym - 101532D Counting Test 前缀和统计字符串
题意:给你一个1e4长的字符串S,有1e5个询问,每个询问形如 l r c ,其中l,r为左右边界,c为所询问的字符.注意,l,r,可以大于串S的长度,这种情况下认为S自身重复无数次(S+S+S··· ...
- IOS UIView圆角,阴影,边框,渐增光泽
圆角 sampleView.layer.cornerRadius = 2.5; // 圓角的弧度sampleView.layer.masksToBounds = YES; 阴影 sampleView. ...
- sublime安装install package
通过 https://sublime.wbond.net/Package%20Control.sublime-package 下载packageControl文件 下载完成后,打开sublime te ...
- python2.X编码
1.Python文件的编码 在Python文件中,可以在第一或第二行指定文件的编码格式(以注释的形式加),这也是Python语法规定的,见http://www.python.org/peps/pep- ...
- hibernate注解(一)JoinColumn
@Entity @Table(name="t_group") public class Group { private int id; private String name; p ...
- 在scrapy中使用mongodb管道
pipelines.py import json from scrapy.conf import settings from pymongo import MongoClient class SunP ...
- VMware上安装VMware tools
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/walkerkalr/article/details/34896407 VMware上安装VMw ...