VC++中内存对齐实例教程_C 语言

内存对其是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++程序设计有所帮助。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索vc++
内存对齐
c语言内存对齐、c语言结构体内存对齐、vc c语言 内存泄漏、vc6.0自动对齐、vc对齐快捷键,以便于您获取更多的相关知识。

时间: 2024-09-15 23:20:44

VC++中内存对齐实例教程_C 语言的相关文章

C语言泛型编程实例教程_C 语言

本文实例讲述了C语言泛型编程的方法,分享给大家供大家参考之用.具体分析如下: 首先,泛型编程让你编写完全一般化并可重复使用的算法,其效率与针对某特定数据类型而设计的算法相同.在C语言中,可以通过一些手段实现这样的泛型编程.这里介绍一种方法--通过无类型指针void* 看下面的一个实现交换两个元素内容的函数swap,以整型int为例: void swap(int* i1,int* i2){ int temp; temp = *i1; *i1 = *i2; *i2 = temp; } 当你想交换两个

C语言循环结构与时间函数用法实例教程_C 语言

本文实例展示了C语言循环结构与时间函数用法,对于C语言的学习来说是非常不错的参考借鉴材料.分享给大家供大家参考之用.具体如下: 完整实例代码如下: /********************************************** ** <Beginning C 4th Edition> Notes codes ** Created by Goopand ** Compiler: gcc 4.7.0 *****************************************

C++类中的static和const用法实例教程_C 语言

static和const是C++程序设计中非常重要的概念,本文实例列举了C++类中的static和const的规则和用法.供大家参考借鉴.具体说明如下: 首先以代码用来举例说明.示例代码如下: class A { public: A():m(10) //const成员必须在构造函数的初始化构造列表中初始化 { q = 40; } void fun1()const { m++; //错误.const成员是常量,不能改变其值. n++; //正确.static变量n属于类,但是每个对象的函数都可以访

C++中基类和派生类之间的转换实例教程_C 语言

本文实例讲解了C++中基类和派生类之间的转换.对于深入理解C++面向对象程序设计有一定的帮助作用.此处需要注意:本文实例讲解内容的前提是派生类继承基类的方式是公有继承,关键字public.具体分析如下: 以下程序为讲解示例: #include<iostream> using namespace std; class A { public: A(int m1, int n1):m(m1), n(n1){} void display(); private: int m; int n; }; voi

Linux中使用C语言的fork()函数创建子进程的实例教程_C 语言

一.fork入门知识一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事. 一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间.然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同.相当于克隆了一个自己.   我们来看一个例子: #include <unistd.h> #include &l

C语言创建和操作单链表数据结构的实例教程_C 语言

1,为什么要用到链表 数组作为存放同类数据的集合,给我们在程序设计时带来很多的方便,增加了灵活性.但数组也同样存在一些弊病.如数组的大小在定义时要事先规定,不能在程序中进行调整,这样一来,在程序设计中针对不同问题有时需要3 0个大小的数组,有时需要5 0个数组的大小,难于统一.我们只能够根据可能的最大需求来定义数组,常常会造成一定存储空间的浪费. 我们希望构造动态的数组,随时可以调整数组的大小,以满足不同问题的需要.链表就是我们需要的动态数组.它是在程序的执行过程中根据需要有数据存储就向系统要求

MFC之ComboBox控件用法实例教程_C 语言

本文以实例形式较为详细的讲述了MFC中ComboBox控件的用法.分享给大家供大家参考之用.具体方法如下: 一.ComboBox简介: ComboBox控件是由一个文本输入控件和一个下拉菜单组成的.用户可以从一个预先定义的列表里选择一个选项,同时也可以直接在文本框里面输入文本. 从工具栏中拖一个Combo Box控件.右击添加变量,变量名为cbBox. 二.用法: 1.为控件添加选项,指定默认选项 cbBox.AddString(_T("one")); cbBox.AddString(

C语言压缩文件和用MD5算法校验文件完整性的实例教程_C 语言

使用lzma SDK对7z文件简单解压缩有时候我们只需要单纯对lzma算法压缩的7z文件进行解压,有时需要在嵌入式设备上解压,使用p7zip虽然支持多种格式,但是不容易裁剪,使用lzma SDK是首选: 可以在这里找到各种版本:http://zh.sourceforge.jp/projects/sfnet_sevenzip/releases/ 我下载了4.65版本,这个对文件名编码支持没有9.20的好,中文可能有问题,但是我的需求不需要支持中文文件名,所以足够用了. 解压后先看一下7z这个工程,

C语言变量类型与输出控制用法实例教程_C 语言

本文实例讲述了C语言变量类型与输出控制用法,有助于读者很好的对其进行总结与归纳.该实例分享给大家供大家参考借鉴之用.具体如下: 完整实例代码如下: /********************************************** **<Beginning C 4th Edition>Notes codes ** Created by Goopand ** Compiler: gcc 4.7.0 *******************************************