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 ...
随机推荐
- 9.java 操作mongodb插入、读取、修改以及删除基础
1 package mongodb; import java.net.UnknownHostException; import java.util.ArrayList; import java.uti ...
- orm 通用方法——QueryModelById 主键查询
方法定义: /** * 描述:根据主键查询 * 作者:Tianqi * 日期:2014-09-15 * param:model 对象实例,包含主键 * return:对象 * */ func Quer ...
- 是时候抛弃web.xml了?
你是否再为配置文件web.xml容易出错而烦恼?是否为web.xml文件存放位置而不知所措?是否为web.xml为什么要这样配?怎么才能更好的配置web.xml而烦恼?那么一种新的方式出现了: spr ...
- sql的四大函数
字符串函数: 1.charindex(字符串表达式 1, 字符串表达式2[,整数表达式]) select charindex('ab','BCabTabD')返回 3 select charindex ...
- 【Henu ACM Round#18 C】Ilya and Sticks
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 用cnt[i]记录数字i出现的次数就好. 然后i从1e6逆序到1 如果cnt[i+1]和cnt[i]>0同时成立的话. 那么得 ...
- [Python] Manipulate Data with Dictionaries in Python
Dictionaries may be familiar to you as hash maps. In this lesson, you will learn how to create them, ...
- codeforces 543 C Remembering Strings
题意:若一个字符串集合里的每一个字符串都至少有一个字符满足在i位上,仅仅有它有,那么这个就是合法的,给出全部串的每一个字符修改的花费,求变成合法的最小代价. 做法:dp[i][j].前i个串的状态为j ...
- C#变量的作用域
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- LinkedIn微服务框架rest.li
linkedin/rest.li https://github.com/linkedin/rest.li LinkedIn微服务框架rest.li摘要:Rest.li是一款REST+JSON框架,使 ...
- Android 关于::app:clean :app:preBuild UP-TO-DATE :app:preDebugBuild UP-TO-DATE,引用jar冲突问题
错误提示: Information:Gradle tasks [:app:clean, :app:generateDebugSources, :app:generateDebugAndroidTest ...