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

 更新时间:2014年08月23日 10:18:18   投稿:shichen2014  
这篇文章主要介绍了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++程序设计有所帮助。

相关文章

  • C/C++读取大文件数据方式详细讲解

    C/C++读取大文件数据方式详细讲解

    这篇文章主要介绍了C语言/C++读取大文件数据的完整方式过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-09-09
  • uboot添加自定义命令的实现步骤

    uboot添加自定义命令的实现步骤

    uboot 属于bootloader的一种,是用来引导启动内核的,它的最终目的就是从flash中读出内核,放到内存中,启动内核,这篇文章主要介绍了uboot添加自定义命令的实现步骤,需要的朋友可以参考下
    2022-11-11
  • C语言双指针多方法旋转数组解题LeetCode

    C语言双指针多方法旋转数组解题LeetCode

    这篇文章主要为大家介绍了C语言双指针使用多方法旋转数组题解LeetCode,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-02-02
  • C++特殊类设计概念与示例讲解

    C++特殊类设计概念与示例讲解

    本文介绍C++中三种特殊类设计模式:单例模式、工厂模式和代理模式。通过详细讲解每种设计模式的实现原理和应用场景,帮助读者理解和掌握这些常用的面向对象设计模式,并提供示例代码和技巧,便于实际应用
    2023-04-04
  • C++设计模式之建造者模式(Builder)

    C++设计模式之建造者模式(Builder)

    这篇文章主要介绍了C++设计模式之建造者模式Builder的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • C++获取多浏览器上网历史记录示例代码(支持获取IE/Chrome/FireFox)

    C++获取多浏览器上网历史记录示例代码(支持获取IE/Chrome/FireFox)

    这篇文章主要介绍了C++获取多浏览器上网历史记录示例代码,支持获取IE, Chrome,FireFox等浏览器
    2013-11-11
  • c语言计算三角形面积代码

    c语言计算三角形面积代码

    c语言计算三角形面积,这只是一个小作业,大家一起学习C语言吧,面积公式s = (a+b+c) / 2 area = sqrt(s * (s - a) * (s - b) * (s - c))
    2013-11-11
  • C++ 数据类型强制转化的实现

    C++ 数据类型强制转化的实现

    这篇文章主要介绍了C++ 数据类型强制转化的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • c++ 如何在libuv中实现tcp服务器

    c++ 如何在libuv中实现tcp服务器

    这篇文章主要介绍了c++ 如何在libuv中实现tcp服务器,帮助大家更好的理解和使用libuv,感兴趣的朋友可以了解下
    2021-02-02
  • 基于Matlab实现人工神经网络(ANN)回归的示例详解

    基于Matlab实现人工神经网络(ANN)回归的示例详解

    这篇文章主要为大家详细介绍了Matlab实现人工神经网络(ANN)回归的相关资料,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-02-02

最新评论