`

【C++ Primer】 神秘的 sizeof(union) 、sizeof(struct) 和内存对齐技术

 
阅读更多

一,union:C/C++关键字 共用体(联合)

共用体的声明和共用体变量定义与结构十分相似。形式为:


共用体表示几个变量共用一个内存位置,在不同的时间保存不同的数据类型和不同长度的变量.在union中,所有的共用体成员共用一个空间,并且同一时间只能储存其中一个成员变量的值。当一个共用体被声明时, 编译程序自动地产生一个变量, 其长度为联合中最大的变量长度的整数倍(特别注意数组)

例子一:

union foo{

  int i;

  char c;

  double k;

  };


sizeof(foo); //double最长占用8字节,所以union foo大小为8字节

例子二: 


sizeof(A) ; //24 而不是20 ???

sizeof(B) ; //48 而不是???

对齐: 分配内存时,每个成员放在长度倍数位置,如果不够,补位对齐

补齐: 对整个结构变量的空间要求总长度一定是最长的成员的倍数,不够补齐不管是对齐还是补齐,最长的成员长度超过4时,以4计。

A实际占用内存大小为 20字节,但是要跟 8个字节的变量double的整数倍,对齐所以为 24;

由于A实际占用24字节,则可以想象B实际占用38字节,但A是8字节对齐的,所以int n和char c[10]也需要8字节对齐,总共8+24+16=48 字节。

例子三:


sizeof(f); // 12
解释:在这个union中,foo的内存空间的长度为12,是int型的3倍,而并不是数组的长度10。
若把int改为double,则foo的内存空间为16,是double型的两倍。

二,struct

具体说明见内存对齐例子

三,内存对齐

1)概念:“内存对齐”应该是编译器的“管辖范围”。编译器为程序中的每个“数据单元”安排在适当的位置上。

2)原因:

1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。   

2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因是:为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

3)对齐规则

  每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。   

规则:   

1、数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。   

2、结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。   

3、结合1、2可推断:当#pragma pack的n值等于或超过所有数据成员长度的时候,这个n值的大小将不产生任何效果。

pragma pack(1) 时候

1>数据成员对齐:


sizeof(test_t) ; //输出为13

2>整体对齐

   整体对齐系数 = min((max(int,short,char), 1) = 1

   整体大小(size)=$(成员总大小) 按 $(整体对齐系数) 圆整 = 13 /*13%1=0*/


pragma pack(2) 时候

1>成员数据对齐

  

  成员总大小=14

  2> 整体对齐

  整体对齐系数 = min((max(int,short,char), 2) = 2

  整体大小(size)=$(成员总大小) 按 $(整体对齐系数) 圆整 = 14 /* 14%2=0 */

四,终极例子

入门例子一:


sizeof(B); // 24

B中采用double长度 8字节对齐方式,所以A在结构体B内 变成8字节。实际B占用8+8+1=17。再填充成8的整数倍后位 24字节

变态例子二:

sizeof(B); //16

如果你的第一反应是24那么你就躺着中枪了。想想为什么吧!!


分享到:
评论

相关推荐

    C++Primer习题集第五版 pdf

    习题集 【中图法分类号】TP312-44 【内容提要】 C++Primer(FifthEdition)由三位C++大师StanleyB.Lippman、JoséeLajoie和BarbaraE.Moo合作完成,其中文译本《C++Primer中文版(第5版)》也已出版。与上一版相比,本书...

    C++Primer课程详细视频讲解

    该视频是关于C++ Primer 这本书的猎豹详细视频初级高级讲解 该视频是关于C++ Primer 这本书的猎豹详细视频初级高级讲解 该视频是关于C++ Primer 这本书的猎豹详细视频初级高级讲解 该视频是关于C++ Primer 这本书的...

    C++Primer 习题解答(第4版)--绝对完整版

    《C++ Primer 习题解答(第4版)》是一本深入C++编程语言的实践指导书籍,由Lippman, Lajoie, 和 Moo三位专家编写。这本习题解答是针对C++ Primer(第四版)教材的,旨在帮助读者巩固和深化对C++的理解。在学习C++的...

    C++ Primer编程习题集(第5版).pdf

    C++ Primer编程习题集(第5版),有习题和编程代码,供自我检验使用

    C++Primer Plus附录源码等文件.zip

    《C++ Primer Plus》是Stephen Prata撰写的一本广受欢迎的C++编程教材,第六版提供了深入浅出的C++语言教程,旨在帮助初学者和有一定经验的程序员掌握这一强大的编程语言。附录中的源码文件是作者为配合书中的教学...

    C++ primer Plus的pdf资源

    C++ primer Plus的pdf资源

    C++primer中文第五版

    在C++ Primer的第五版中,作者们对C++11和C++14的新特性进行了详尽的讲解,包括自动类型推导、右值引用、lambda表达式、并发编程以及模板元编程等。这些新特性极大地增强了C++的现代性和效率,使得C++在保持高性能的...

    c++ primer plus 答案 c++ primer plus 答案

    "c++ primer plus 答案"的搜索和讨论反映了读者在学习过程中对解决问题和理解概念的需求。 C++是一种通用的、面向对象的编程语言,由Bjarne Stroustrup于1979年在贝尔实验室创建,它是C语言的增强版,引入了类、...

    C++ primer中文版-高清-带目录

    4. **指针与引用**:解释了指针和引用的概念,如何通过它们操作内存和实现高效编程。 5. **模板**:阐述模板在函数和类中的应用,包括函数模板、类模板以及模板元编程。 6. **异常处理**:介绍C++的错误处理机制,...

    C++primer第四版源代码

    2. **指针与引用**:C++中的指针是内存地址的别名,而引用是另一个变量的别名,它们在内存管理中起到关键作用,尤其是在动态内存分配和函数参数传递时。 3. **类与对象**:C++的核心是面向对象编程,类是定义对象...

    C++ Primer 5th 英文高清版 (带完整目录)

    《C++ Primer 5th》是C++编程领域的一部权威著作,由Lippman、Lajoie和 Moo三位专家合著。这本书以其深入浅出的讲解方式和丰富的实例,深受程序员们的喜爱。5th版更是针对C++11、C++14和C++17标准进行了全面更新,...

    c++primer高清中文版-第5版.zip

    C++是一门强大、难学、令人痛苦,但又是如此美妙的编程语言,在工业界和学术界都可以使用,《C++ Primer(第5版)》即针对初学者,也同样适用于有一定编程经验的读者,第5版配备了C++11新标准,是C++粉丝们书架上...

    c++ primer 第5版 英文版 原版精美排版 mobi格式 kindle直读

    《C++ Primer》是C++编程领域的一本经典著作,第五版更是深受程序员喜爱的教程。这本书详尽地介绍了C++语言,从基础语法到高级特性,为读者提供了全面而深入的学习路径。作为英文版,它保持了原汁原味的专业表达,...

    C++Primer中文版第5版.pdf

    C++Primer中文版第5版

    C++Primer读书笔记:C++概述.pdf

    C++Primer中文第三版(C++从入门到精通)第一章的读书笔记,主要是C++程序、预处理器指示符、iostream库等的基础知识点读书笔记。

    C++ Primer(Fifth Edition)(英文版+中文版)

    《C++ Primer (Fifth Edition)》是C++编程领域的一部经典著作,由Lippman、Lajoie和 Moo三位作者共同编写。这本第五版的书籍是为那些希望深入理解和掌握C++语言的程序员准备的,无论是初学者还是经验丰富的开发者,...

    c++ primer有目录pdf第五版本5th

    《C++ Primer》是有名的C++编程教材,其第五版(5th Edition)深入浅出地介绍了C++语言的基础知识以及C++11新标准的特性。这本书由Lippman、Lajoie和 Moo三位作者共同编写,是C++初学者和进阶者的重要参考书籍。 1....

    C++ Primer第四版【中文高清扫描版】.pdf

    《C++ Primer 第四版》是著名的C++编程语言教程,由Stanley B. Lippman、Josée Lajoie和Barbara E. Moo三位作者共同撰写。该书自出版以来,已成为广大程序员学习C++的必备书籍。第四版对前三版的内容进行了彻底的...

Global site tag (gtag.js) - Google Analytics