‘壹’ c语言结构体长度字节对齐问题
因为当结构体中有多个数据类型时,结构体的长度对齐是按数据类型长度最长的那个来对齐的,double类型占8个字节,所以每个成员变量都按8个字节的长度来算,就是5*8=40,验证程序如下:
#include<stdio.h>
structchji
{
charname[9];
intnumber;
charsex;
doublescore;
floataa;
};
structchjistu;
intmain()
{
printf("sizeof(structchji)=%d ",sizeof(structchji));
return0;
}
运行结果:sizeof(struct chji)=40
如果要按单个字节的长度来对齐的话,代码如下:
#include<stdio.h>
#pragmapack(1)
structchji
{
charname[9];//9
intnumber;//4
charsex;//1
doublescore;//8
floataa;//4
};
structchjistu;
#pragmapack()
intmain()
{
printf("sizeof(structchji)=%d ",sizeof(structchji));
return0;
}
运行结果:sizeof(struct chji)=26
即9+4+1+8+4=26,你可以查下#pragma pack()相关的资料的,就会清楚了。
‘贰’ C语言字节对齐问题
看样子跟你用的编译器有关系,
你用的是gcc 什么版本的,最新的是4.9吧
‘叁’ c语言,怎么解决结构体字节对齐问题或者说是否有一个函数能使未知结构体转换成一字节对齐的字节数组
结构体中多定义一个无关的数据类型,这个数据类型的长度要和原有长度构成结构体的对齐
‘肆’ C语言字节对齐
应该是把A当成了 char 和 int 类型来进行对齐吧
‘伍’ C语言结构体怎么对齐按最大字节对齐struct pp{int a;float b; doubl
24(按8字节对齐,前面int和float合起来刚好8字节+double8字节+char补齐后8字节=24)
如果是struct pp{int a;float b; char d}oo; sizeof(oo)就是12字节,按4字节对齐
‘陆’ C语言字节对齐问题
这个占多少个字节是不确定的!!!跟编译器有关的!!
对于visual
c++来说:
int
4字节
char
1字节
float
4字节
long
4字节
double
8字节
而对于gcc的编译器来说
double占12字节!
‘柒’ 什么是C语言结构体字节对齐,为什么要对齐
对齐跟数据在内存中的位置有关。如果一个变量的内存地址正好位于它长度的整数倍,他就被称做自然对齐。比如在32位cpu下,假设一个整型变量的地址为0x00000004,那它就是自然对齐的。
需要字节对齐的根本原因在于CPU访问数据的效率问题。假设上面整型变量的地址不是自然对齐,比如为0x00000002,则CPU如果取它的值的话需要访问两次内存,第一次取从0x00000002-0x00000003的一个short,第二次取从0x00000004-0x00000005的一个short然后组合得到所要的数据,如果变量在0x00000003地址上的话则要访问三次内存,第一次为char,第二次为short,第三次为char,然后组合得到整型数据。而如果变量在自然对齐位置上,则只要一次就可以取出数据。一些系统对对齐要求非常严格,比如sparc系统,如果取未对齐的数据会发生错误,举个例:
char ch[8];
char *p = &ch[1];
int i = *(int *)p;
运行时会报segment error,而在x86上就不会出现错误,只是效率下降。
‘捌’ c语言结构体字节对齐(某马)
但是实际上cpu将内存当成多个块,每次从内存中读取一个块,这个块的大小可能是2、4、8、16等。
那么下面,我们来分析下非内存对齐和内存对齐的优缺点在哪?
内存对齐是操作系统为了提高访问内存的策略。操作系统在访问内存的时候,每次读取一定长度(这个长度是操作系统默认的对齐数,或者默认对齐数的整数倍)。如果没有对齐,为了访问一个变量可能产生二次访问。
至此大家应该能够简单明白,为什么要简单内存对齐?
‘玖’ c语言结构体对齐的问题。
这是个好问题!
为什么会有对齐的问题呢?简单的说就是为了提高访问内存的效率,这和CPU内部的机制有关,如果你想深入理解,需要阅读 Intel 开发者手册。对齐采用的总体原则是这样的:4字节变量的存放要对齐到可以被4整除的地址上,8字节变量的存放要对齐到可以被8整除的地址上。其他变量类推就行了。如果没对齐编译器就会将某个变量的存储往后推迟几个字节,以保证对齐后再存放。
具体到这个问题就是可以先假设结构体变量从地址0处开始存放,那么第一种情况就是这样的了:
cat 存放的位置是地址0-地址3
a数组存放的位置是地址4-地址23
dog存放的位置是地址24到地址31
这里可以看到它们都符合对齐的原则(即每个变量开始存放的地址可以除尽它们所占的字节数),所以是32
第二种情况是这样的:
cat仍然存放到地址0-地址3处
a数组是地址4到地址27处
存放dog时编译器计算除下一个地址28并不能除尽double的字节数8,于是它要将地址进行递增。29,30,31仍然不能除尽8,知道递增到32时可以将8除尽了,所以dog变量会被存放在地址32到地址39处,从地址0到地址39正好40个字节,这就解释了第二种情况了。
ps. 其实你这个问题还有一种变种就是一个结构体里在套一个结构体,这时会牵扯到内部的结构体对齐的问题。等你以后遇见了再给我提问吧,我给你解释。
‘拾’ 关于C语言中的结构体字节对齐
仔细看一下书中的说明吧,这三言两语介绍起来有点累
或从网上查阅相关的技术资料,有详细描述。
一般简单来说,结构体从第一个变量开始检查空间的“对齐字节数”,
默认以第一个字节大小作为对齐字节数,如果遇上的下一个字节与当前对齐字节数不同时,就按两者中较大的来进行结构体空间分配,接下来的对齐就全按此值来对齐,直到再遇上不同的才进行检查或改变。