关于结构体的字节对齐是什么,就不赘述,再此附上一篇文章,介绍字节对齐:http://www.linuxsong.org/2010/09/c-byte-alignment/

这里的结构体字节对齐的数据类型都是基本数据类型,如果结构体的定义中含有结构体成员呢?

网上有很多人写博客谈到这个问题,都认为该结构体成员应该被看做一个整体,按照整体的字节数来进行字节对齐,选择首地址。但是经过测试,这种说法是不对的。

 struct s1{
char c1;
char c2;
char c3;
char c4;
}; struct s2{
char a;
struct s1 s;
};

对于上述代码,显然sizeof(struct s1) = 4。如果将struct s1看做整体,来进行字节对齐的话,sizeof(struct s2)应该是等于8。但是该段代码在gcc和VS2010下测试的结果都是5。

所以,s2的内存布局如下

s2 : char | char char char char |

s的首地址并非为4,而是char类型长度的整数倍

同样,对于结构体:

 struct S1
{
char a;
short b;
}; struct S2
{
char a;
struct S1 s;
};

上述代码中,sizeof(struct S1) = 4,而sizeof(struct S2) = 6。

S2的内存布局是:

S2 : char **** | char **** short short

s的首地址并非为4,而是short类型长度的整数倍,结构体S2的长度并非结构体S1长度的整数倍,而是short类型长度的整数倍

相对的,我们可以看一下结构体:

struct S
{
char a;
char b;
short c;
};

sizeof(S) = 4。

其内存布局为:

S : char char short short

对比S2和S,我们看到,S2中的s结构体成员确实是仍按它作为S1结构体的整体(占用4个字节)来布局的。

那么我们可以得出这情形下的字节对齐问题的结论:

1)结构体中的结构体成员,是按照原结构体的内存布局在新结构体中进行布局的;

2)结构体中的结构体成员,其内存首地址为该成员中最长数据类型的整数倍;

3)结构体的整体长度与其中的结构体成员无关,而是整个结构体(包括结构体成员内部)中的最长数据类型的整数倍。

得出结论后,我们回到处理器本身,来探讨一下编译器之所以这么处理的原因。

从CPU结构角度看内存对齐有一篇比较易懂的文章:

http://hi.baidu.com/maikeai/item/4976f24cc0f905d3c1a592a0

从该文章中,我们可以知道,之所以需要内存对齐,是CPU为了读取数据时减少读取存储器的次数,提高效率。

对于32位的CPU,一次最多读入双字的32位数据,而对于超过32位的数据,在32位的计算机上,就必须多次读取存储器,这与是否字节对齐无关。

我们可以看到,字节对齐,其实实质上是在拿存储器的空间,换CPU的时间。

所以,对于C语言内置的数据类型,可以很好地通过内存对齐来节省时间,同时其浪费的存储器空间也是可控的。

但是,对于结构体成员来说,因为它的长度是不可控的,所以如果强行按整体内存对齐,首先可能因为长度过长,即使内存对齐需要的存储器读取次数也很多,导致优化的时间不明显,另外,也可能导致浪费的存储器空间太大。所以,最简单的平衡空间和时间的方法,就是按照该结构体成员中最长数据类型来进行字节对齐,这样最有可能减少存储器读取次数,也使浪费的存储器空间可控。

关于C语言中结构体中的结构体成员导致的字节对齐问题的更多相关文章

  1. C语言提高 (5) 第五天 结构体,结构体对齐 文件

    1昨日回顾 2作业讲解 3 结构体的基本定义 //1 struct teacher { int id; char name[64]; }; struct teacher t5 = { 5, " ...

  2. C语言中的字节对齐以及其相关处理

    首先,我们来了解下一些基本原理: 一.什么是字节对齐一个基本类型的变量在内存中占用n个字节,则该变量的起始地址必须能够被n整除,即: 存放起始地址 % n = 0,那么,就成该变量是字节对齐的;对于结 ...

  3. [置顶] 什么是C语言结构体字节对齐,为什么要对齐?

    一.概念 对齐跟数据在内存中的位置有关.如果一个变量的内存地址正好位于它长度的整数倍,他就被称做自然对齐.比如在32位cpu下,假设一个整型变量的地址为0x00000004,那它就是自然对齐的.   ...

  4. C语言结构体变量字节对齐问题总结

    结构体字节对齐 在用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题.从理论上讲,对于任何 变量的访问都可以从任何地址开始访问,但 ...

  5. C语言中的字节对齐

    下面这个篇博客讲解很好 http://blog.csdn.net/meegomeego/article/details/9393783 总的来看分三类: 1. 不加 #pragma pack(n)伪指 ...

  6. stm32中使用#pragma pack(非常有用的字节对齐用法说明)

    #pragma pack(4)   //按4字节对齐,但实际上由于结构体中单个成员的最大占用字节数为2字节,因此实际还是按2字节对齐 typedef struct { char buf[3];//bu ...

  7. C/C++ 结构体字节对齐

    在用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题.从理论上讲,对于任何 变量的访问都可以从任何地址开始访问,但是事实上不是如此 ...

  8. ACE的CDR中的字节对齐问题

    大家应该都知道计算机中间都有字节对齐问题.CPU访问内存的时候,如果从特定的地址开始访问一般可以加快速度,比如在32位机器上,如果一个32位的整数被放在能被32模除等于0的地址上,只需要访问一次,而如 ...

  9. C语言字节对齐问题详解

    引言 考虑下面的结构体定义: typedef struct{ char c1; short s; char c2; int i; }T_FOO; 假设这个结构体的成员在内存中是紧凑排列的,且c1的起始 ...

随机推荐

  1. xml、txt、config的一些基本用法

    先来测试一下xml的读取好了创建了一个student.xml的文件 <?xml version="1.0" encoding="UTF-8"?> & ...

  2. 诡异的_DEBUG宏

    学习VLD1.0代码,发现Release版本的代码_DEBUG宏是已定义的,查找工程配置确只有NDEBUG宏的定义,不见_DEBUG的踪影. 好吧,最后发现是由于工程Code Generation选项 ...

  3. php 日期 - 计算2个日期的差值

    /** * 日期-计算2个日期的差值 * @return int */ public function get_difference($date, $new_date) { $date = strto ...

  4. hdu 5126 stars cdq分治套cdq分治+树状数组

    题目链接 给n个操作, 第一种是在x, y, z这个点+1. 第二种询问(x1, y1, z1). (x2, y2, z2)之间的总值. 用一次cdq分治可以将三维变两维, 两次的话就变成一维了, 然 ...

  5. cocos2d-x box2d使用调试绘图

    cocos2d-x box2d使用调试绘图 复制TestCpp的GLES-Render.h和GLES-Render.cpp过来. 添加一个成员变量: GLESDebugDraw *m_debugDra ...

  6. SQL Server创建LinkServer

    USE [master] GO /****** Object: LinkedServer [xxx_LNK] Script Date: 2014/7/7 17:04:13 ******/ EXEC m ...

  7. <!DOCTYPE html>

    html5标准网页声明,原先的是一串很长的字符串,现在是这个简洁形式,支持html5标准的主流浏览器都认识这个声明.表示网页采用html5.

  8. Java调用.dll文件

    因为项目的需求,要在JAVA项目中调用Windows的Dll(动态链接库)文件,之前用Jni调用过C写的Dll文件,比较麻烦,这里不多说,网上也有很多这方面的文档.在网上找到一个开源的组件JNativ ...

  9. 使用kd-tree加速k-means

    0.目录 前置知识 思路介绍 详述 1 确定h的中心点 2 算法步骤 java实现 1.前置知识 本文内容基于<Accelerating exact k-means algorithms wit ...

  10. Python学习笔记2-Python神奇的语法和格式化输出

    先来看一个例子: class Fish: hungry=True def eat(self,food): if food is not None: self.hungry=False class Us ...