我们经常看到求 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++中内存对齐的更多相关文章

  1. C语言中内存对齐规则讨论(struct)

    C语言中内存对齐规则讨论(struct) 对齐: 现代计算机中内存空间都是按着byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地 ...

  2. C语言中内存对齐

    今天一考研同学问我一个问题,一个结构体有一个int类型成员和一个char类型成员,问我这个结构体类型占多少个字节,我直接编个程序给他看结果.这个结构体占八个字节,咦,当时我蛮纳闷的,一个int类型四个 ...

  3. C语言中内存对齐方式

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

  4. c语言中内存对齐问题

    在最近的项目中,我们涉及到了“内存对齐”技术.对于大部分程序员来说,“内存对齐”对他们来说都应该是“透明的”.“内存对齐”应该是编译器的“管辖范围”.编译器为程序中的每个“数据单元”安排在适当的位置上 ...

  5. C/C++中内存对齐问题的一些理解(转)

    内存对齐指令 一般来说,内存对齐过程对coding者来说是透明的,是由编译器控制完成的 如对内存对齐有明确要求,可用#pragma pack(n)指定,以n和结构体中最长数据成员长度中较小者为有效值 ...

  6. 什么是内存对齐,go中内存对齐分析

    内存对齐 什么是内存对齐 为什么需要内存对齐 减少次数 保障原子性 对齐系数 对齐规则 总结 参考 内存对齐 什么是内存对齐 弄明白什么是内存对齐的时候,先来看一个demo type s struct ...

  7. C语言中内存对齐与结构体

    结构体 结构体是一种新的数据类型,对C语言的数据类型进行了极大的扩充. struct STU{ int age; char name[15]; }; struct STU a; //结构体实例 str ...

  8. c/c++中内存对齐完全理解

    一,什么是内存对齐?内存对齐用来做什么? 所谓内存对齐,是为了让内存存取更有效率而采用的一种编译阶段优化内存存取的手段. 比如对于int x;(这里假设sizeof(int)==4),因为cpu对内存 ...

  9. VC中结构体的内存布局

    看了 VC++中内存对齐 这篇文章,感觉说复杂了,根据我的总结,要算出结构体的内存大小和偏移量,只要清楚结构体各成员的内存布局就行了,下面介绍一下我总结的规则,有不对之处,欢迎回复. 1.实际PACK ...

随机推荐

  1. Database Corruption ->> Fix Database In Suspect State

    昨天在工作中遇到一个情况,就是Development环境中的某台服务器上的某个数据库进入了Suspect状态.以前看书倒是知道说这个状态,不过实际工作当中从来没有遇到过.那么一些背景情况是这样的. 环 ...

  2. 界面上传文件js包【AjaxUpload.js】

    function uploadFile() { new AjaxUpload($("#importFile"), { action: url, type: "POST&q ...

  3. UI抑制限制(UI Suppression Limitations)

    运行UI抑制的Lync进程使你的应用程序可以访问同一个Lync客户端终端,SIP处理和所有非抑制Lync客户端使用的媒体处理,但具有以下限制.SDK中的可见组件不可用,除了视频窗体(video win ...

  4. Win XP 如何禁用系统的自动更新

    想关闭系统的自动更新. 打开[控制面板]/[安全中心],发现“自动更新”和“更改安全中心通知我的方式”,都已成了灰色,无法更改. 网上查了一下,找到了这样一个处理方法:将[服务]中一个名为“Autom ...

  5. JNI层问题

    1. make:进入目录'/opt/FriendlyARM/tiny4412/android/android-4.1.2'make: *** 没有规则可以创建“out/target/product/g ...

  6. PHP包含文件函数include、include_once、require、require_once区别总结

    一.使用语法和简介 1.include() 语法:include(/path/to/filename)include()语句将在其被调用的位置处包含一个文件.包含一个文件与在该语句所在位置复制制定文件 ...

  7. 如何获取supersocket的源代码

    源代码的地址:https://github.com/kerryjiang/SuperSocket 安装git之后,可以使用命令行git clone https://github.com/kerryji ...

  8. 关于结构化BOM的思考

    参加了今天的"自主生产音箱类产品BOM结构问题"(即非采购而是制造的音箱)会议,我发现大家在会议上呈现的产品结构对生产计划的层级需求已上升到5层的需求了,又找段会胜要了各位前期就此 ...

  9. leetcode:Multiply Strings

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

  10. 设置Sublime Text2 中代码提示

    打开sublime text的菜单 Preferences -> Package Settings -> GoSublime ->Settings – User  然后输入 { &q ...