VC++中内存对齐
我们经常看到求 sizeof(A) 的值的问题,其中A是一个结构体,类,或者联合体。
为了优化CPU访问和优化内存,减少内存碎片,编译器对内存对齐制定了一些规则。但是,不同的编译器可能有不同的实现,本文只针对VC++编译器,这里使用的IDE是VS2012。
#pragma pack()是一个预处理,表示内存对齐。布局控制#pragma,为编译程序提供非常规的控制流信息。
/**********结构体的大小的规则*************/
结构体大小是处理器位数和结构体内最长数据元素所占字节数二者中较小的那一个的整数倍。
比如说,假设处理器位数为n,结构体内最大数据元素所占字节数为m。
处理器为32位,n = 4;结构体内最大数据类型为short,m = 2; n > m;结构体大小为m的整数倍,反之亦然。
注意:有些虽然是64位的操作系统,但是编译器却是32位的,此时位数为32.
class A{
int a;
char b;
short c;
};
sizeof(A)为8,为4的整数倍。
struct B{
short a;
short b;
short c;
};
sizeof(B)为6,为2(sizeof(short))的整数倍。
注意:C++中的结构体与类只有一个区别,就是结构体成员默认是public,而类默认是private。
class X{
public:
double a;
float b;
int c;
char d;
};
sizeof(X)为20,为4(处理器位数)的整数倍。
/********* #pragma pack(n) *************/
#pragma pack(n)中的n默认是4,即处理器位数32,但我们可以自己定义它的大小。
#pragma pack(1)
class A{
public:
int a;
char b;
short c;
};
此时sizeof(A)为7,为1(#pragma pack(1))的整数倍。
#pragma pack(1)
class X{
public:
double a;
int b;
short c;
char d;
};
sizeof(X)为15,为1(#pragma pack(1))的整数倍。
#pragma pack(4)
class X{
public:
double a;
int b;
short c;
char d;
};
sizeof(X)为16,为4(#pragma pack(4))的整数倍。
#pragma pack(8)
class X{
public:
double a;
int b;
short c;
char d;
};
sizeof(X)为16,为8(#pragma pack(8) 或者 sizeof(double))的整数倍。
/***************内存对齐**************/
结构体中数据元素所在内存地址由两个因素决定。
一是#pragma pack(n) 中的n,二是元素类型所占字节数,sizeof(type),两者中取较小的一个,元素内存地址到结构体或类的起始地址的偏移量为较小数的整数倍。
比如#pragma pack(n)默认为4,有以下结构体
struct A{
int a;
char b;
short c;
};
a的起始地址距离结构体起始地址的偏移量为0,是sizeof(int)的整数倍。
b的起始地址距离结构体起始地址的偏移量为4,是sizeof(char)的整数倍。
c的起始地址距离结构体起始地址的偏移量为5,不是sizeof(short)的整数倍,所以它的起始地址偏移量将会是6,而不是5。
输出a, b, c 的地址为
0043FD68
0043FD6C
0043FD6E
可以看到c的起始地址比b的起始地址大了2个字节,b占了2个字节的大小,这是因为c的类型是short型,大小为2,而n默认是4,sizeof(short) < n,所以偏移量应该是2的整数倍,这里是6.
VC++中内存对齐的更多相关文章
- C语言中内存对齐规则讨论(struct)
C语言中内存对齐规则讨论(struct) 对齐: 现代计算机中内存空间都是按着byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地 ...
- C语言中内存对齐
今天一考研同学问我一个问题,一个结构体有一个int类型成员和一个char类型成员,问我这个结构体类型占多少个字节,我直接编个程序给他看结果.这个结构体占八个字节,咦,当时我蛮纳闷的,一个int类型四个 ...
- C语言中内存对齐方式
一.什么是对齐,以及为什么要对齐: 1. 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问, ...
- c语言中内存对齐问题
在最近的项目中,我们涉及到了“内存对齐”技术.对于大部分程序员来说,“内存对齐”对他们来说都应该是“透明的”.“内存对齐”应该是编译器的“管辖范围”.编译器为程序中的每个“数据单元”安排在适当的位置上 ...
- C/C++中内存对齐问题的一些理解(转)
内存对齐指令 一般来说,内存对齐过程对coding者来说是透明的,是由编译器控制完成的 如对内存对齐有明确要求,可用#pragma pack(n)指定,以n和结构体中最长数据成员长度中较小者为有效值 ...
- 什么是内存对齐,go中内存对齐分析
内存对齐 什么是内存对齐 为什么需要内存对齐 减少次数 保障原子性 对齐系数 对齐规则 总结 参考 内存对齐 什么是内存对齐 弄明白什么是内存对齐的时候,先来看一个demo type s struct ...
- C语言中内存对齐与结构体
结构体 结构体是一种新的数据类型,对C语言的数据类型进行了极大的扩充. struct STU{ int age; char name[15]; }; struct STU a; //结构体实例 str ...
- c/c++中内存对齐完全理解
一,什么是内存对齐?内存对齐用来做什么? 所谓内存对齐,是为了让内存存取更有效率而采用的一种编译阶段优化内存存取的手段. 比如对于int x;(这里假设sizeof(int)==4),因为cpu对内存 ...
- VC中结构体的内存布局
看了 VC++中内存对齐 这篇文章,感觉说复杂了,根据我的总结,要算出结构体的内存大小和偏移量,只要清楚结构体各成员的内存布局就行了,下面介绍一下我总结的规则,有不对之处,欢迎回复. 1.实际PACK ...
随机推荐
- C++:流类库与输入输出
7.2.1 C++的输入输出流 ios:流基类(抽象类) istream:通用输入流类和其他输入流的基类 ostream:通用输出流类和其他输出类的基类 iostream:通用输入输出流类和其他输入输 ...
- Data Flow ->> OLE Command
这里有篇博客文章是讲这个OLE Command的:http://www.cnblogs.com/tylerdonet/archive/2011/06/20/2085490.html OLE Comma ...
- 常用WinPE
微PE工具箱:http://www.wepe.com.cn/ 绝对PE工具箱:http://dl.pconline.com.cn/download/64736.html 通用PE工具箱:http:// ...
- android 更改avd路径
第一种方法,适合还没有建立 AVD 的情况 即:在计算机右击的属性 选择环境变量,然后添加一个用户的环境变量,名字为 "ANDROID_SDK_HOME”,然后把变量值改为你想将" ...
- excel读取 工具类
package cn.yongche.utils; import java.io.File; import java.io.FileInputStream; import java.io.IOExce ...
- MySQL工具:管理员必备的10款MySQL工具
MySQL是一个复杂的的系统,需要许多工具来修复,诊断和优化它.幸运的是,对于管理员,MySQL已经吸引了很多软件开发商推出高品质的开源工具来解决MySQL的系统的复杂性,性能和稳定性,其中大部分是免 ...
- JWFD开源项目官方网站预览
自己做的...感觉还比较正规哈....JWFD开源项目还是需要一个官方网站的...
- BZOJ 1494 生成树计数(生成树计数-矩阵)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1494 题意: 思路: int SIZE; struct matrix { i64 a[N] ...
- cdoj 1329 卿学姐与魔法 优先队列
卿学姐与魔法 Time Limit: 1200/800MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...
- Android应用更新升级实现
介绍 在产品的开发中,android升级提示,下载更新是必备的功能,否则等用户被动去官方网,或者第三方商店提示,就为时已晚了. 原理 在用户每次打开应用的时候,都与服务器进行一次交互,获取版本信息,对 ...