windows和Linux内存的对齐方式
struct xx{
char b;
int a;
int c;
char d;
};
{
struct xx bb;
printf("&a = %p\n", &bb.a);
printf("&b = %p\n", &bb.b);
printf("&c = %p\n", &bb.c);
printf("&d = %p\n", &bb.d);
printf("sizeof(xx) = %d\n", sizeof(struct xx));
}
&b = ffbff5e8
&c = ffbff5f0
&d = ffbff5f4
sizeof(xx) = 16
struct xx{
char b;
char d;
int a;
int c;
};
#pragma pack(4)
struct xx{
char b;
long long a;
int c;
char d;
};
#pragma pack()
{
struct xx bb;
printf("&a = %p\n", &bb.a);
printf("&b = %p\n", &bb.b);
printf("&c = %p\n", &bb.c);
printf("&d = %p\n", &bb.d);
printf("sizeof(xx) = %d\n", sizeof(struct xx));
}
打印结果为:
&b = ffbff5e0
&c = ffbff5ec
&d = ffbff5f0
sizeof(xx) = 20
内存对齐是操作系统为了高速訪问内存而採取的一种策略,简单来说,就是为了放置变量的二次訪问。操作系统在訪问内存 时,每次读取一定的长度(这个长度就是操作系统的默认对齐系数,或者是默认对齐系数的整数倍)。假设没有内存对齐时,为了读取一个变量是,会产生总线的二 次訪问。
char b; //0xffbff5e8
int a; //0xffbff5e9
int c; //0xffbff5ed
char d; //0xffbff5f1
};
内存对齐的问题主要存在于理解struct等复合结构在内存中的分布。
很多实际的计算机系统对基本类型数据在内存中存放的位置有限制。它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数。这就是所谓的内存对齐。
我们的开发主要涉及两大平台。windows和linux(unix)。涉及的编译器也主要是microsoft编译器(如cl),和gcc。
明确了这两点基本上就能搞定全部内存对齐方面的问题。
1、对于microsoft的编译器,每种基本类型的大小即为这个k。大体上char类型为8。int为32,long为32。double为64。
2、对于linux下的gcc编译器,规定大小小于等于2的。k值为其大小,大于等于4的为4。
struct test1
{
char a;
short b;
int c;
long d;
double e;
};
最后到e,他的k值为8。首地址为8的倍数,所以地址12,13,14。15被填充。他的首地址应为16,占用地址16-23。显然其大小为24。
然后从低地址依次打印出内存中每一个字节相应的16进制数为:
2 0 4 0 8 0 0 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 40 40
显然判断是正确的。
如果从0地址開始。首先a的k值为1,它的首地址能够使任何位置,所以a占用第一个字节。即地址0。然后b的k值为2,他的首地址必须是2的倍数。不能是1。所以地址1那个字节被填充,b首地址为地址2,占用地址2。3;然后到c。c的k值为4。他的首地址为4的倍数,所以首地址为4。占用地址4。5,6。7;再然后到d,d的k值也为4。所以他的首地址为8,占用地址8,9。10。11。
最后到e,从这里開始与microsoft的编译器開始有所差异,他的k值为不是8,仍然是4,所以其首地址是12,占用地址12-19。显然其大小为20。
我们建立一个test1类型的变量。a、b、c、d、e分别赋值2、4、8、16、32。
然后从低地址依次打印出内存中每一个字节相应的16进制数为:
2 0 4 0 8 0 0 0 10 0 0 0 0 0 0 0 0 0 40 40
struct test2
{
char f;
struct test1 g;
};
所以test2相对于test1来说添加了4个字节,所以test2的大小为24。
{
unsigned int a:4;
unsigned int b:4;
char c;
};
或者
struct test3
{
unsigned int a:4;
int b:4;
char c;
};
如:test3中。a、b可作为一个总体。他们作为一个int型数据来看待,所以test3的大小为8字节。而且a与b的值在内存中从低位開始依次排列,位于4字节区域中的前0-3位和4-7位
struct test4
{
unsigned int a:30;
unsigned int b:4;
char c;
};
那么test4的大小就为12个字节,而且a与b的值分别分布在第一个4字节的前30位。和第二个4字节的前4位。
struct test5
{
unsigned int a:4;
unsigned char b:4;
char c;
};
{
unsigned int a:4;
unsigned int b:4;
char c;
};
gcc下,相邻各成员。无论类型是否同样。占的位数之和超过这些成员中第一个的大小的时候,在结构中以k值为1对齐,在结构外k值为其基本类型的值。
不超过的情况下在内存中依次排列。
如test3。其大小为4。a,b的值在内存中依次排列分别为第一个四字节中的0-3和4-7位。
struct test4
{
unsigned int a:20;
unsigned char b:4;
char c;
};
test4的大小为4个字节,而且a与b的值分别分布在第一个4字节的0-19位,和20-23位,c存放在第4个字节中。
如过test5是下面形式
struct test5
{
unsigned int a:10;
unsigned char b:4;
short c;
};
假设a的大小变成了20
那么test5的大小应为8字节。
即
{
unsigned int a:20;
unsigned char b:4;
short c;
};
windows和Linux内存的对齐方式的更多相关文章
- linux内存使用计算方式
Linux开机后,使用top命令查看,4G物理内存发现已使用的多大3.2G,占用率高达80%以上: Mem: 3889836k total, 3341868k used, 547968k free, ...
- 【转】进程间通信方式总结(windows 和linux)
平时看的书很多,了解的也很多,但不喜欢总结,这不昨天面试的时候被问到了进程间通信的方式,因为没有认真总结过,所以昨天答得不是特别好.现在将linux和windows的进程间通信方式好好总结一下. ...
- Windows与Linux下进程间通信技术比较
一般我们写的程序都是以单个进程的方式来运行的,比较少涉及到多进程.特别是在windows下,因为Windows是按照线程来分配CPU时间片的,线程是最小的调度单位,所以在Windows下更多的用到多线 ...
- 开发问题(一)在windows和linux端口占用问题
前言 今天在MyEclipse中使用tomcat发现tomcat端口8080竟然被占用了,所以就找了一下解决办法共参考! 在网络程序的调试过程中,经常发生一些出乎意料的事情,比如创建一个TCP服务失败 ...
- C语言中内存对齐方式
一.什么是对齐,以及为什么要对齐: 1. 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问, ...
- Windows内存管理和linux内存管理
windows内存管理 windows 内存管理方式主要分为:页式管理,段式管理,段页式管理. 页式管理的基本原理是将各进程的虚拟空间划分为若干个长度相等的页:页式管理把内存空间按照页的大小划分成片或 ...
- 关于arm处理器 内存编址模式 与 字节对齐方式 (转)
转自:http://bavon.bokee.com/5429805.html 在x86+Linux上写的程序,在PC机上运行得很好.可是使用ARM的gcc进行交叉编译,再送到DaVinci目标板上运行 ...
- windows与linux之间文件的传输方式总结(转)
当然,windows与linux之间文件的传输的两种方式有很多,这里就仅仅列出工作中遇到的,作为笔记: 方法一:安装SSH Secure Shell Client客户端 安装即可登录直接拖拉到linu ...
- linux与windows 通过SecureCRT进行文件传输方式
linux与windows 通过SecureCRT进行文件传输方式 方式一:lrzsz是一款在Linux里可代替ftp上传和下载的程序.(小文件推荐,以4G为界限) # rz -bash: rz: c ...
随机推荐
- IBM软件技术峰会归来
为期两天在北京国际饭店会议中心的IBM软件技术峰会已近结束,此次大会最大的收获是能和沃森实验室的王博士沟通探讨人工智能软件的发展问题.领略到IBM 云计算首席架构师Jason R.McGee如何呼风唤 ...
- Spatial Pyramid Matching
转自:http://blog.csdn.net/jwh_bupt/article/details/9625469 SPM 全称是Spatial Pyramid Matching,出现的背景是bag o ...
- 应对加密js的三种方法
经常遇到网页在登录后会对用户输入的帐号和密码通过js进行加密,导致模拟登录这类网站时受到阻碍 这里小记一下当前解决该问题的三种方法 1.利用python实现js同等加密. 2.利用selenium模拟 ...
- ES6学习笔记(十)代理器Proxy
Java可以使用面向切面(AOP)的方法来实现某些统一的操作,比如某个操作的前置通知,后置通知等等,这种操作非常方便,其本质便是动态代理,JS的代理Proxy代理该如何使用呢? 某位大神的实现如下: ...
- JS之预编译和执行顺序(全局和函数)
预编译的两种情况 全局: 1.全局 直接是script标签中的代码,不包括函数执行 执行前: 1.首先生成一个GO(global object)对象,看不到,但是可以模拟出来用来分析 2.分析变量声明 ...
- 学习《Python数据科学手册》高清中文PDF+高清英文PDF+代码
如果有一定的数据分析与机器学习理论与实践基础,<Python数据科学手册>这本书是绝佳选择. 是对以数据深度需求为中心的科学.研究以及针对计算和统计方法的参考书.很友好实用,结构很清晰.但 ...
- 【Python】【Head First Python】【chapter1】1 - 导入模块
导入模块 导入模块有三种方法,以导入sys模块为例: 第一是import module 形式导入 import sys location = sys.stdout 第二是from module imp ...
- Java图像渐变
图像渐变我们大体想一下思路无非是这样:将图像所有的像素点的RBG,每个点就减去相同的量,而且这个量是个渐变的量.是的,就是这样,我们的程序也是这个思路,不过就是没有单纯的“想”这么简单了.我这里只编写 ...
- JS中的预解析
js预解析对于很多学习web前端开发的新手们很困扰,总是很难搞懂到底是个什么东西,今天零度就为大家简单的分析一下,争取让大家都明白! 首先,看一下下面的代码: alert(a); var a = 1; ...
- POJ 1991 DP
题意: 思路: 考虑DP 先把事件按照地点顺序排个序 f[i][j][0]表示从i到j还没有去过 现在在i f[i][j][1]表示从i到j还没有去过 现在在j 那么方程就呼之欲出了 f[i][j][ ...