VC++中内存对齐实例教程

内存对其是VC++程序设计中一个非常重要的技巧,本文即以实例讲述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++程序设计有所帮助。

(0)

相关推荐

  • C语言、C++内存对齐问题详解

    这也可以? 复制代码 代码如下: #include <iostream> using namespace std;   struct Test_A {      char a;      char b;      int c; };   struct Test_B {      char a;      int c;      char b; };   struct Test_C {      int c;      char a;      char b; };   int main() {

  • 深入理解c/c++ 内存对齐

    内存对齐,memory alignment.为了提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐.原因在于,为了访问未对齐的内存,处理器需要作两次内存访问:然而,对齐的内存访问仅需要一次访问.内存对齐一般讲就是cpu access memory的效率(提高运行速度)和准确性(在一些条件下,如果没有对齐会导致数据不同步现象).依赖cpu,平台和编译器的不同.一些cpu要求较高(这句话说的不准确,但是确实依赖cpu的不同),而有些平台已经优化内存对齐问题,不同编译器的对齐模数不同.总

  • C++中的内存对齐实例详解

    C++中的内存对齐实例详解 内存对齐 在我们的程序中,数据结构还有变量等等都需要占有内存,在很多系统中,它都要求内存分配的时候要对齐,这样做的好处就是可以提高访问内存的速度. 我们还是先来看一段简单的程序: 程序一 #include <iostream> using namespace std; struct X1 { int i;//4个字节 char c1;//1个字节 char c2;//1个字节 }; struct X2 { char c1;//1个字节 int i;//4个字节 ch

  • VC++中内存对齐实例教程

    内存对其是VC++程序设计中一个非常重要的技巧,本文即以实例讲述VC++实现内存对其的方法.具体分析如下: 一.概述 我们经常看到求 sizeof(A) 的值的问题,其中A是一个结构体,类,或者联合体. 为了优化CPU访问和优化内存,减少内存碎片,编译器对内存对齐制定了一些规则.但是,不同的编译器可能有不同的实现,本文只针对VC++编译器,这里使用的IDE是VS2012. #pragma pack()是一个预处理,表示内存对齐.布局控制#pragma,为编译程序提供非常规的控制流信息. 二.结构

  • C语言结构体中内存对齐的问题理解

    目录 前言 思考 结构体在内存中开辟空间时内存对齐的规则 为什么存在内存对齐 1.平台的原因 2.性能的原因 前言 学C的同学应该知道~ 想精通C语言就不得不面对—指针与内存 续上次指针的进阶,这一章我来聊一聊C语言内存对齐的问题 学习结构体的你有没有注意过结构体向系统申请的内存为多少呢的 思考 #include<stdio.h> typedef struct s1 { char a; char b; int c; }s1; typedef struct s2 { char a; int c;

  • C语言中结构体与内存对齐实例解析

    1.结构体类型 C语言中的2种类型:原生类型和自定义类型,结构体类型是一种自定义类型. 2.结构体使用时先定义结构体类型再用类型定义变量 -> 结构体定义时需要先定义结构体类型,然后再用类型来定义变量. -> 也可以在定义结构体类型的同时定义结构体变量. // 定义类型 struct people { char name[20]; int age; }; // 定义类型的同时定义变量. struct student { char name[20]; int age; }s1; // 将类型st

  • C语言内存对齐实例详解

    本文详细讲述了C语言程序设计中内存对其的概念与用法.分享给大家供大家参考之用.具体如下: 一.字节对齐基本概念 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐. 对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同.一些平台对某些特定类型的数据只能从某些特定地址开始存取.比如有些架构的C

  • ThinkPHP中ajax使用实例教程

    本文实例讲述了ThinkPHP中使用ajax的方法,提交表单如下图所示: 点击提交,不需要刷新本页,将内容提交到数据库当中,并在本页显示提交的内容.如下图所示: 一.jquery实现方法: MessageAction.class.php页面代码如下: <?php class MessageAction extends Action{ function index(){ $this->display(); } function add(){ //ajaxReturn(数据,'提示信息',状态)

  • python中的多线程实例教程

    本文以实例形式较为详细的讲述了Python中多线程的用法,在Python程序设计中有着比较广泛的应用.分享给大家供大家参考之用.具体分析如下: python中关于多线程的操作可以使用thread和threading模块来实现,其中thread模块在Py3中已经改名为_thread,不再推荐使用.而threading模块是在thread之上进行了封装,也是推荐使用的多线程模块,本文主要基于threading模块进行介绍.在某些版本中thread模块可能不存在,要使用dump_threading来代

  • C#中lock死锁实例教程

    在c#中有个关键字lock,它的作用是锁定某一代码块,让同一时间只有一个线程访问该代码块,本文就来谈谈lock关键字的原理和其中应注意的几个问题: lock的使用原型是: lock(X) { //需要锁定的代码.... } 首先要明白为什么上面这段话能够锁定代码,其中的奥妙就是X这个对象,事实上X是任意一种引用类型,它在这儿起的作用就是任何线程执行到lock(X)时候,X需要独享才能运行下面的代码,若假定现在有3个线程A,B,C都执行到了lock(X)而ABC因为此时都占有X,这时ABC就要停下

  • Oracle中的定时任务实例教程

    目录 一.Oracle 中的定时任务的实例 1.1.创建一个测试表,只有一个 DATE 类型字段 1.2.创建一个自定义存储过程 1.3.创建定时任务JOB 1.4.运行JOB (1.3执行成功后,job就已经开始执行了) 1.5.关于JOB的查询操作 1.6.常见的Interval 设置 1.7.编写存储过程的格式样例 补充:Oracle手动执行定时任务 总结 一.Oracle 中的定时任务的实例 1.1.创建一个测试表,只有一个 DATE 类型字段 CREATE TABLE TEST_A(T

  • js位运算在实际中使用的实例教程

    目录 什么是位运算? 业务场景: 解决办法 办法一: 办法二: 附:位运算的综合应用 总结 什么是位运算? 从现代计算机中所有的数据二进制的形式存储在设备中.即 0.1 两种状态,计算机对二进制数据进行的运算(+.-.*./)都是叫位运算,即将符号位共同参与运算的运算. 按位运算符有6个 &: 按位与\|: 按位或\^: 按位异或\~: 按位取反\>> : 右移\<<: 左移 业务场景: 我们大部分的业务开发场景下 只用if else 或 switch 条件处理就可以,但是

随机推荐