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

 更新时间:2021年05月08日 15:03:05   作者:℃绝心恋  
这篇文章主要给大家介绍了关于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++计算结构体对象大小内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言指针和数组深入探究使用方法

    C语言指针和数组深入探究使用方法

    在C语言和C++等语言中,数组元素全为指针变量的数组称为指针数组,指针数组中的元素都必须具有相同的存储类型、指向相同数据类型的指针变量。指针数组比较适合用来指向若干个字符串,使字符串处理更加方便、灵活
    2022-08-08
  • C 语言的弱符号与弱引用你了解吗

    C 语言的弱符号与弱引用你了解吗

    这篇文章主要为大家详细介绍了C 语言弱符号与弱引用,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • FFmpeg中avfilter模块的介绍与使用

    FFmpeg中avfilter模块的介绍与使用

    FFmpeg中的libavfilter模块(或库)用于filter(过滤器), filter可以有多个输入和多个输出,下面就跟随小编一起简单学习一下它的巨日使用吧
    2023-08-08
  • c++双向链表操作示例(创建双向链、双向链表中查找数据、插入数据等)

    c++双向链表操作示例(创建双向链、双向链表中查找数据、插入数据等)

    这篇文章主要介绍了c++双向链表操作示例,包括创建双向链、删除双向链表、双向链表中查找数据、插入数据等,需要的朋友可以参考下
    2014-05-05
  • static全局变量与普通的全局变量的区别详细解析

    static全局变量与普通的全局变量的区别详细解析

    以下是对static全局变量与普通的全局变量的区别进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2013-09-09
  • 论C++的lambda是函数还是对象

    论C++的lambda是函数还是对象

    这篇文章主要介绍了论C++的lambda是函数还是对象,对于有捕获的lambda,其等价于对象。对于没有任何捕获的lambda,其等价于函数,下面来看看具体的相关内容,需要的朋友可以参考一下
    2022-02-02
  • QT实现将两个时间相加的算法[hh: mm + hh: mm]的示例代码

    QT实现将两个时间相加的算法[hh: mm + hh: mm]的示例代码

    本文主要介绍了QT实现将两个时间相加的算法[hh: mm + hh: mm]的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • VC多线程编程详解

    VC多线程编程详解

    这篇文章主要介绍了VC多线程编程,实例形式详细分析了多线程编程的原理与实现方法,具有一定的参考借鉴价值,需要的朋友可以参考下
    2014-10-10
  • 详解C语言之单链表

    详解C语言之单链表

    这篇文章主要为大家介绍了C语言的单链表,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-11-11
  • C++ Boost PointerContainer智能指针详解

    C++ Boost PointerContainer智能指针详解

    智能指针是一种像指针的C++对象,但它能够在对象不使用的时候自己销毁掉。虽然STL提供了auto_ptr,但是由于不能同容器一起使用(不支持拷贝和赋值操作),因此很少有人使用。它是Boost各组件中,应用最为广泛的一个
    2022-11-11

最新评论