C++如何计算结构体与对象的大小

如何计算结构体的大小

其实计算一个结构的大小的方法并不难,简单来说就是把结构体内的所有成员的大小相加就可以。但是,需要内存对齐那么究竟什么是内存对齐,又为什么要进行类型对齐呢?

结构体的内存对齐

结构体内存对齐主要有两个步骤:

1.结构体各成员对齐.
2.结构体总体对齐

结构体内存对齐规则:

1.结构体的第一个成员在存放在结构体偏移量为0的位置
2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。.

对齐数 = 编译器默认的一个对齐数与该成员大小的较小值。
/*
**VS中默认的值为8
**Linux中的默认值为4
*/

3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。

4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

说了这么多,我们直接在VS环境下举几个例子给大家说明一下:

例1:

struct S1
{
 char c1;
 int i;
 char c2;
};

(1)计算这个结构体的大小的时候,首先看c1的大小是1(char类型),也即是说在结构体中c1存放的位置是结构体偏移量是0的位置

(2)接下来看i占4个字节,根据结构体对齐规则可知,c的有效对齐值为4(4 < 8)对齐到4的整数倍地址,即地址偏移量为4处.(40的位置存放了c1,所以只能从41的位置开始存放)

(3)同(2)得出c2的存储位置是8

(4)此时内存中共有9个字节,进行结构体整体对齐,最大对齐数是4,即要求是4的整数倍,也就是12

例2:

struct S1
{
	char c1;
	int i;
	char c2;
};
struct S2
{
	char a1;
	struct S1 s1;
	int i;
};

上面我们知道S1的大小是12,现在我们计算一下S2的大小:

(1)a1占一个字节,放在结构体变量偏移量为0 的地址处.

(2) s1占12个字节,对齐数位4(嵌套的结构体对齐到自己的最大对齐数的整数倍处,S1的最大对齐数是4),40处存放了a1,所以只能从41处开始存放

(3)i占了4字节,对齐数为4,s1一直存放到了15的位置,所以i只能从4*5 = 20的位置开始存储

(4)现在内存中共有20个字节,成员中最大对齐数是4,整体对齐时为4的倍数,所以结果是20

注意:默认对齐参数是可以用#pragma pack()设置的,例如下面的这个例子

#include <stdio.h>
#include <Windows.h>
#pragma pack(8)//设置默认对齐数为8
struct S1
{
	char c1;
	int i;
	char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
#pragma pack(1)//设置默认对齐数为1
struct S2
{
	char c1;
	int i;
	char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
int main()
{
	//输出的结果是什么?
	printf("%d\n", sizeof(struct S1));
	printf("%d\n", sizeof(struct S2));
	system("pause");
	return 0;
}

为什么存在内存对齐

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

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

如何计算一个对象的大小

其实在C++中,结构体和类可以认为是相同的,只是默认的访问权限不同(struct默认是public,class默认是private ),从这方面来看的话,其实计算一个类/对象的大小的方法和计算结构体的大小的方法是一样的。
我们来验证一下:

#include <iostream>
using namespace std;

struct A
{
	int a;
	char b;
	char c;
};
class B
{
	int a;
	char b;
	char c;
};

int main()
{
	cout << sizeof(A) << endl;
	cout << sizeof(B) << endl;
	system("pause");
	return 0;
}

可以看到,我们对结构体A和类B计算大小是一样的。

总结

到此这篇关于C++如何计算结构体与对象大小的文章就介绍到这了,更多相关C++计算结构体对象大小内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++如何计算结构体与对象的大小

    如何计算结构体的大小 其实计算一个结构的大小的方法并不难,简单来说就是把结构体内的所有成员的大小相加就可以.但是,需要内存对齐那么究竟什么是内存对齐,又为什么要进行类型对齐呢? 结构体的内存对齐 结构体内存对齐主要有两个步骤: 1.结构体各成员对齐. 2.结构体总体对齐 结构体内存对齐规则: 1.结构体的第一个成员在存放在结构体偏移量为0的位置 2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处.. 对齐数 = 编译器默认的一个对齐数与该成员大小的较小值. /* **VS中默认的值为8

  • 浅谈C语言结构体

    目录 前言 什么是结构体 结构体类型的声明 结构的自引用 结构体变量的定义和初始化 结构体的使用 结构体内存对齐 结构体传参 总结 前言 在C语言中,除了内置的许多数据类型,C语言还为我们提供了自定义的数据类型,其中就包括结构体这一数据类型. 今天就让我们来学习一下与结构体相关的知识吧! 什么是结构体 首先我们要知道,什么是结构体? 在现实生活中,每一个事物都是复杂的,拥有许多的属性,为了表示这些属性,我们不可能用单一的数据类型来表示. 例如:一只猫具有的属性有:年龄.体重.名字.品种等等. 为

  • C语言结构体(struct)常见使用方法(细节问题)

    基本定义:结构体,通俗讲就像是打包封装,把一些有共同特征(比如同属于某一类事物的属性,往往是某种业务相关属性的聚合)的变量封装在内部,通过一定方法访问修改内部变量. 结构体定义: 第一种:只有结构体定义 struct stuff{ char job[20]; int age; float height; }; 第二种:附加该结构体类型的"结构体变量"的初始化的结构体定义 //直接带变量名Huqinwei struct stuff{ char job[20]; int age; floa

  • C语言结构体占用内存深入讲解

    前言 前几天有个小朋友问了我一下,关于C语言结构体占用空间的问题.觉得以后会对小可爱有点帮助,就打算先写一下. struct Test { int a; char b; int c; } test; 理论上,结构体中的各个成员在内存中应该是连续储存的,就像数组里面的元素一样.事实上,也确实是这个样子的,不过和我们想象的有点不一样. 按照我们最初的想法,变量test所占的内存为 4 + 1 + 4 = 9. 但是我们写一个小代码验证一下发现和我们想的不一样. 它的内存为12.因为 int类型是4个

  • 如何用python实现结构体数组

    目录 python结构体数组 在NumPy中可以如下定义 内存对齐 python自定义结构体 具体方法如下 python结构体数组 在C语言中我们可以通过struct关键字定义结构类型,结构中的字段占据连续的内存空间,每个结构体占用的内存大小都相同,因此可以很容易地定义结构数组. 和C语言一样,在NumPy中也很容易对这种结构数组进行操作. 只要NumPy中的结构定义和C语言中的定义相同,NumPy就可以很方便地读取C语言的结构数组的二进制数据,转换为NumPy的结构数组. 假设我们需要定义一个

  • 深入剖析C++中的struct结构体字节对齐

    什么是字节对齐,为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐. 对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同.一些平台对某些特定类型的数据只能从某些特定地址开始存取.比如有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证

  • C#结构体特性实例分析

    本文实例讲述了C#结构体特性.分享给大家供大家参考.具体如下: 结构体的定义: 结构体也可以象类一样可以单独定义. class a{}; struct a{}; 结构体也可以在名字前面加入控制访问符. public struct student{}; internal struct student{}; 如果结构体student没有publice或者internal的声明 类program就无法使用student结构定义 obj对象 如果结构体student的元素没有public的声明,对象ob

  • 解析结构体的定义及使用详解

    结构的定义 定义一个结构的一般形式为: struct 结构名 { 成员表列 }成员表由若干个成员组成,每个成员都是该结构的一个组成部分.对每个成员也必须作类型说明. 例如: 复制代码 代码如下: struct stu { int num; char name[20]; int age; } 结构类型变量的说明结构体定义并不是定义一个变量,而是定义了一种数据类型,这种类型是你定义的,它可以和语言本身所自有的简单数据类型一样使用(如 int ).结构体本身并不会被作为数据而开辟内存,真正作为数据而在

  • C++结构体字节对齐和共用体大小

    目录 1.结构体内存对齐 2.共用体的内存大小 3.枚举的大小 1.结构体内存对齐 结构体内存对齐在笔试和面试中经常被问到,所以做个总结 通过代码验证不同结构体的内存大小: #include <stdio.h> struct Node1{ char c1; int val1; char c2; }; struct Node2{ char c1; char c2; int val1; }; struct Node3{ char c1; char array[10]; }; struct Node

  • C语言详解结构体的内存对齐与大小计算

    目录 结构体的内存对齐 1.计算结构体的大小 2.结构体的对齐规则 3.为什么存在内存对齐? 4.总结 结构体的内存对齐 1.计算结构体的大小 struct S1 { char c1; // 1 byte,默认对齐数为8,所以c1的对齐数是1,第一个成员变量放在与结构体变量偏移量为0的地址处 int i; // 4 byte,默认对齐数为8,所以i的对齐数是4,所以i要放到偏移量为 4的整数倍 的地址处 char c2; // 1 byte,默认对齐数为8,所以c2的对齐数是1,所以c2要放到偏

随机推荐