接上一篇:C语言内存对齐详解(2)

在minix的stdarg.h文件中,定义了如下一个宏:

/* Amount of space required in an argument list for an arg of type TYPE.
* TYPE may alternatively be an expression whose type is used.
*/ #define __va_rounded_size(TYPE) \
(((sizeof (TYPE) + sizeof (int) - ) / sizeof (int)) * sizeof (int))

从注释以及宏的名字可以看出是有关内存对齐方面的作用。根据前两篇关于C语言内存对齐方面的理论可知

n字节对齐就是说变量存放的起始地址的偏移量有两种情况:

第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式(各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数);

第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。

此时n = 4,对于sizeof(TYPE)一定为自然数,sizeof(int) - 1 = 3

sizeof(TYPE)只可能出现如下两种情况:

(1) 当sizeof(TYPE) >= 4,偏移量 = (sizeof(TYPE)/4)*4

(2) 当sizeof(TYPE) < 4,偏移量 = 4

此时sizeof(TYPE) = 1 or 2 or 3,而(sizeof(TYPE) + 3) / 4  = 1

为了将上述两种情况统一,偏移量 = ((sizeof(TYPE) + 3) / 4) * 4


在有的源代码中,将内存对齐宏__va_rounded_size通过位操作来实现,代码如下:

#define __va_rounded_size(TYPE)  \
((sizeof(TYPE)+sizeof(int)-)&~(sizeof(int)-))

由于 ~(sizeof(int) – 1) ) = ~(4-1)=~(00000011B)=11111100B

(sizeof(TYPE) + sizeof(int) – 1)就是将大于4m但小于等于4(m+1)的数提高到大于等于4(m+1)但小于4(m+2),这样再& ~(sizeof(int) – 1) )后就正好将原长度补齐到4的倍数了。

C语言内存对齐详解(3)的更多相关文章

  1. C语言内存对齐详解(2)

    接上一篇:C语言内存对齐详解(1) VC对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式.VC 中提供了#pr ...

  2. C语言内存对齐详解

    一.字节对齐基本概念 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型 ...

  3. C语言内存对齐详解(1)

    一.什么是字节对齐,为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这 ...

  4. [转]C++结构体|类 内存对齐详解

    内存地址对齐,是一种在计算机内存中排列数据(表现为变量的地址).访问数据(表现为CPU读取数据)的一种方式,包含了两种相互独立又相互关联的部分:基本数据对齐和结构体数据对齐 . 为什么需要内存对齐?对 ...

  5. C/C++内存对齐详解

    1.什么是内存对齐 还是用一个例子带出这个问题,看下面的小程序,理论上,32位系统下,int占4byte,char占一个byte,那么将它们放到一个结构体中应该占4+1=5byte:但是实际上,通过运 ...

  6. 3.c语言结构体成员内存对齐详解

    一.关键一点 最关键的一点:结构体在内存中是一个矩形,而不是一个不规则形状 二.编程实战 #include <stdlib.h> #include <stdio.h> stru ...

  7. 【转载】图说C++对象模型:对象内存布局详解

    原文: 图说C++对象模型:对象内存布局详解 正文 回到顶部 0.前言 文章较长,而且内容相对来说比较枯燥,希望对C++对象的内存布局.虚表指针.虚基类指针等有深入了解的朋友可以慢慢看.本文的结论都在 ...

  8. java程序运行时内存分配详解

    java程序运行时内存分配详解 这篇文章主要介绍了java程序运行时内存分配详解 ,需要的朋友可以参考下   一. 基本概念 每运行一个java程序会产生一个java进程,每个java进程可能包含一个 ...

  9. C语言memset函数详解

    C语言memset函数详解 memset() 的作用:在一段内存块中填充某个给定的值,通常用于数组初始化与数组清零. 它是直接操作内存空间,mem即“内存”(memory)的意思.该函数的原型为: # ...

随机推荐

  1. try-catch和throw,throws的区别和联系

    转载:http://blog.sina.com.cn/s/blog_62148d1e0100hkqc.html 区别一:throw 是语句抛出一个异常:throws 是方法抛出一个异常: throw语 ...

  2. 第七章 new的三步曲

    这章是本系列文章的重点,这章揭示了js对象的真正本质 看下面的事例 var a = new b(); 等价于 ①var a={}; ②a.__proto__=b.prototype; ③b.call( ...

  3. C# 6.0部分新特性

    Struct的默认构造函数和属性赋值 我看C# 6 introduce 提到这个功能.但vs2015搭载的NET4.6貌似还不支持这个.所以也不好判断. 属性赋值 /// <summary> ...

  4. 取当前的地址栏的Url和url中的参数

    看到这样一段代码: exports.showLogin = function (req, res) { req.session._loginReferer = req.headers.referer; ...

  5. 我的bootstrap使用的历程

    1.bootstrap快速开发,和amaze一样,同样是自己布局,然后找对应的模板,然后复制. 2.bootstrap实现的不完美的地方,我们要靠自己的样式去解决. 典型的居中布局, containe ...

  6. css渐变

    常这样去定义一个渐变的div: 渐变1:(双色) background: -moz-linear-gradient(top, #456d6c %, #32b66a %); %,#456d6c), co ...

  7. iOS边练边学--NSURLSession、NSURLSessionTask的介绍与使用以及url中包含了中文的处理方法

    一.NSURLSession.NSURLSessionTask的使用步骤 首先创建NSURLSession对象 通过NSURLSession对象创建对应的任务 <1>NSURLSessio ...

  8. Java设计模式-代理模式(Proxy)

    其实每个模式名称就表明了该模式的作用,代理模式就是多一个代理类出来,替原对象进行一些操作,比如我们在租房子的时候回去找中介,为什么呢?因为你对该地区房屋的信息掌握的不够全面,希望找一个更熟悉的人去帮你 ...

  9. 【Gym 100971J】Robots at Warehouse

    题意 链接给你一个n*m的地图,'#'代表墙,‘.’代表可走的,1代表1号机器人,2代表2号机器人,机器人可以上下左右移动到非墙的位置,但不能走到另一个机器人身上.问能否交换1和2的位置. 分析 如果 ...

  10. C#用UPnP穿透内网

    参考了网上的一篇文章,由于时间长了,具体地址不知道了. 引入了一个DLL: Interop.NATUPNPLib.dll,实现穿透局域网,进行Socket通信. using System; using ...