2 lsq100200 lsq100200 于 2016.01.21 16:45 提问

数组和结构体对齐关系,求大神解决!

#include
typedef struct
{

unsigned char a;

unsigned char b;
unsigned int c;

unsigned short d;

unsigned int e;
} ABC;

const unsigned short code1[6] = {0x1607,0x1003,0x1008,0x2001,0x3002,0x4003};
void main(void)
{
ABC * p = (ABC *)&code1[0];
printf("%X\n",p->c);

}
请问:输出的是 0x20011008
为什么不是0x10081003 ?

7个回答

shijian95
shijian95   2016.01.21 18:47
已采纳

这个确实和字节对齐有关系,前提是编译器是32-bit的。
在内存中映射的数据,是这样的:
07 16 03 10 08 10 01 20 02 30 03 40
对于int型,每个占用4个byte,必须是4字节对齐。所以起始地址必须是4的倍数。这是编译器优化的结果。
所以一般在定义结构体的时候,为了避免这个问题,我们往往会重新组织一下数据,进行4字节对齐:
typedef struct
{
unsigned char a;
unsigned char b;
unsigned short d; d和c换一下位置。
unsigned int c;
unsigned int e;
} ABC;
如果不能交换位置,比如图形文件的header,必须是字节一一对齐。那一般采用这个方式:
typedef struct
{
unsigned char a;
unsigned char b;
unsigned char c[4];
unsigned char d[2];
unsigned char e[4];
} ABC;
然后根据平台的大小端转换成正确的值

caozhy
caozhy   Ds   Rxr 2016.01.21 16:49
caozhy
caozhy   Ds   Rxr 2016.01.21 16:49

这个和对齐没关系,intel是小端序的,所以,高位在后面。

caozhy
caozhy   Ds   Rxr 2016.01.21 17:29

看错了,确实是对齐的问题

图片说明

lsq100200
lsq100200   2016.01.21 17:13

p->a=0x07
p->b=0x16

p->c为什么不是输出p->b地址后的4个字节,而是直接跳过0x1003。

caozhy
caozhy   Ds   Rxr 2016.01.21 17:29

这样就看得很清楚了,是不是

91program
91program   Ds   Rxr 2016.01.21 16:56

结构体占用空间的分析

但这个问题,是大端与小端的问题。Intel 是低字节在前,例如:0x1234,在内存中是 0x34 0x12。

caozhy
caozhy 回复91program: 因为我的回答在先,你的回答在后,我们的回答差不多意思,而且我回答错了。如果说不是你照搬我的回答,我都可以理解的话,那么我怀疑你照搬了我的回答,相信你也能理解我。
2 年多之前 回复
91program
91program 回复caozhy: 不好意思!我是按自己理解回答的。凭什么说别人照搬你的!!!
2 年多之前 回复
caozhy
caozhy 呵呵,有时候我也会回答错的。不能照搬我的答案。
2 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
由sizeof求结构体大小时涉及到的数据对齐
本博文转自http://www.cnblogs.com/dolphin0520/    作者:海子 结构体字节对齐       在用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题。从理论上讲,对于任何变量的访问都可以从任何地址开始访问,但是事实上不是如此,实际上访问特定类型的变量只能在特定的地址访问,这就需要各
关于stm32结构体对齐
关于stm32结构体对齐最近使用华大MCU hc32l110系列单片机,该单片机位M0+ 内核,由于该单片机存在4字节对齐问题(后来发现的),定义结构体及变量的地址为4的倍数.比如我定义一个8字节的结构体(8个char型变量),当我从结构体第一个字节复制到8字节的数组的时候,能够正常复制,但当我从第二个字节复制到数组的时候,却从第四个字节复制,但stm32却不存在这种问题,为了解决这种问题需在结构...
C++中结构体的对齐方式
在面试中,常会考到结构体的对齐方式,因此对其进行总结。 1、在没有#pragma pack宏的情况下 struct sA{ double d1; int i1; double d2; char c1; };  原则1:每个成员按类型的大小对齐,即相对于结构体地址的成员地址能被类型大小整除.并且结构体的大小(sizeof(A))必须为成员所含类型中最大值(sizeof(double
结构体对齐问题.
在结构中,编译器为结构的每个成员按其自然对界(alignment)条件分配空间;各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。在缺省情况下,C编译器为每一个变量或是数据单元按其自然对界条件分配空间。    例如,下面的结构各成员空间分配情况。   struct tagTest { char x1; short x2; float
结构体成员的对齐方式
我们都知道每种数据类型占有的内存空间大小都是明确,比如:char类型占一个字节,int类型占4个字节等等。我们可以通过使用sizeof关键字得到各种数据类型的长度: 例如:sizeof(char);//占1个字节  sizeof(int); //占4个字节  sizeof(short); //占2个字节 sizeof(double); //占8个字节 对于结构体来说,
c语言中结构体内存对齐规则详解
对齐:         现代计算机中内存空间都是按着byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就是需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。   对齐的作用:         各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据
C语言字节对齐、结构体对齐最详细的解释
文章最后本人做了一幅图,一看就明白了,这个问题网上讲的不少,但是都没有把问题说透。   一、概念       对齐跟数据在内存中的位置有关。如果一个变量的内存地址正好位于它长度的整数倍,他就被称做自然对齐。比如在32位cpu下,假设一个整型变量的地址为0x00000004,那它就是自然对齐的。      二、为什么要字节对齐       需要字节对齐的根本原因在于CPU访问数
易语言钓鱼源码
求大神买走 求大神买走 易语言钓鱼源码
C++关于结构体对齐
说明: 结构体的sizeof值,并不是简单的将其中各元素所占字节相加,而是要考虑到存储空间的字节对齐问题。这些问题在平时编程的时候也确实不怎么用到,但在一些笔试面试题目中出是常常出现,一、解释 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空间
使用标准C读取文件遇到的结构体对齐问题及其解决办法
在使用结构体读取文件时需要考虑结构体内存对齐问题。