C++ sizeof的各种

C++ sizeof的各种

  • 1. 含有虚函数的类对象的空间大小
  • 2. 虚拟继承的类对象的空间大小
  • 3. 普通变量所占空间大小
  • 4. 复合数据类型(结构体和类)
  • 5. 数组
  • 6. 类型别名
  • 7. 动态分配内存
  • 8. 指针
  • 9. 静态变量
  • 10. 联合体
  • 11. 结构体使用#program pack

1. 含有虚函数的类对象的空间大小

在C++中,含有虚函数的类对象的大小不仅包括其成员变量的大小,还包括一个指向虚函数表(vtable)的指针的大小。这个指针用于动态绑定函数调用。在32位系统中,这个指针通常是4字节,在64位系统中则是8字节。

#include <iostream>class Base {
public:virtual void func() {} //32:4字节,64:8字节
};class Derived : public Base {int a; //4double b; //8
};int main() {std::cout << "Size of Base: " << sizeof(Base) << std::endl; // 8std::cout << "Size of Derived: " << sizeof(Derived) << std::endl; //8+4+8return 0;
}

结果(64位系统)

Size of Base: 8
Size of Derived: 24

2. 虚拟继承的类对象的空间大小

在C++中,虚拟继承用于解决多重继承中的菱形继承问题。虚拟继承会影响类对象的内存布局,因为编译器需要在运行时解决虚基类的共享问题,这通常通过引入指针或指针表来实现。

#include <iostream>
class A{
};
class Base {
public:int baseData;
};class Derived1 : virtual public Base {
public:int derived1Data;
};class Derived2 : virtual public Base {
public:int derived2Data;
};class Final : public Derived1, public Derived2 {
public:int finalData;
};int main() {std::cout << "Size of A: " << sizeof(A) << std::endl; // 1std::cout << "Size of Base: " << sizeof(Base) << std::endl; // 4std::cout << "Size of Derived1: " << sizeof(Derived1) << std::endl; // 4 + 8 + 4 = 16std::cout << "Size of Derived2: " << sizeof(Derived2) << std::endl; // 4 + 8 + 4 = 16std::cout << "Size of Final: " << sizeof(Final) << std::endl; // 8 + 8 + 4 + 4 + 4 + 4 = 32return 0;
}

结果

Size of Base: 4
Size of Derived1: 16
Size of Derived2: 16
Size of Final: 32

对Final类详细解释:
虚基类Base的成员只存在一份,但需要存储指针或指针表以便在运行时正确访问。

8 bytes (虚基类指针 1) +
8 bytes (虚基类指针 2) +
4 bytes (Derived1::derived1Data) +
4 bytes (Derived2::derived2Data) +
4 bytes (Final::finalData) +
4 bytes (Base::baseData)
= 32 bytes

3. 普通变量所占空间大小

在C++中,使用sizeof运算符可以计算普通变量所占用的内存空间大小。不同类型的变量占用的内存空间大小可能因系统架构(如32位和64位)和编译器的不同而有所差异。

以下是一些常见的数据类型及其在不同系统上的典型大小:
在这里插入图片描述
解释对long的sizeof:
在64位系统上,long 类型的大小实际上取决于编译器和操作系统的实现。有些系统(特别是遵循 LP64 数据模型的类 Unix 系统)将 long 定义为 8 个字节,而其他系统(如 Windows)可能会将 long 定义为 4 个字节。

#include <iostream>int main() {std::cout << "Size of char: " << sizeof(char) << " bytes" << std::endl;std::cout << "Size of bool: " << sizeof(bool) << " bytes" << std::endl;std::cout << "Size of short: " << sizeof(short) << " bytes" << std::endl;std::cout << "Size of int: " << sizeof(int) << " bytes" << std::endl;std::cout << "Size of float: " << sizeof(float) << " bytes" << std::endl;std::cout << "Size of double: " << sizeof(double) << " bytes" << std::endl;std::cout << "Size of long: " << sizeof(long) << " bytes" << std::endl;std::cout << "Size of long long: " << sizeof(long long) << " bytes" << std::endl;std::cout << "Size of void*: " << sizeof(void*) << " bytes" << std::endl;return 0;
}

结果

Size of char: 1 bytes
Size of bool: 1 bytes
Size of short: 2 bytes
Size of int: 4 bytes
Size of float: 4 bytes
Size of double: 8 bytes
Size of long: 8 bytes  // 在64位系统上
Size of long long: 8 bytes
Size of void*: 8 bytes  // 在64位系统上

4. 复合数据类型(结构体和类)

#include <iostream>struct MyStruct {int a; // 4double b; // 8char c; // 1 -> 4
};class MyClass {
public:int x; // 4float y; // 4char z; // 1 -> 4
};int main() {std::cout << "Size of MyStruct: " << sizeof(MyStruct) << " bytes" << std::endl; // 对齐后16std::cout << "Size of MyClass: " << sizeof(MyClass) << " bytes" << std::endl; // 对齐后 12return 0;
}

5. 数组

#include <iostream>int main() {int arr[10];std::cout << "Size of int array[10]: " << sizeof(arr) << " bytes" << std::endl; // 4 * 10 = 40return 0;
}

6. 类型别名

#include <iostream>typedef int MyInt;
typedef double MyDouble;int main() {std::cout << "Size of MyInt: " << sizeof(MyInt) << " bytes" << std::endl; // 4std::cout << "Size of MyDouble: " << sizeof(MyDouble) << " bytes" << std::endl; // 8return 0;
}

7. 动态分配内存

#include <iostream>int main() {int* ptr = new int[10];std::cout << "Size of pointer to int[10]: " << sizeof(ptr) << " bytes" << std::endl; // 8std::cout << "Size of dynamically allocated int[10]: " << sizeof(*ptr) * 10 << " bytes" << std::endl; // 4 * 10 = 40delete[] ptr;return 0;
}

8. 指针

在一个64位系统上,所有指针的大小通常是8字节

#include <iostream>int main() {int* intPtr;double* doublePtr;char* charPtr;std::cout << "Size of char pointer: " << sizeof(charPtr) << " bytes" << std::endl; // 8std::cout << "Size of int pointer: " << sizeof(intPtr) << " bytes" << std::endl; // 8std::cout << "Size of double pointer: " << sizeof(doublePtr) << " bytes" << std::endl; // 8return 0;
}

9. 静态变量

静态变量的大小可以用sizeof运算符计算,但它们不计入包含它们的类的实例的大小。

#include <iostream>class MyClassWithStatic {
public:static int staticVar;int regularVar;
};int MyClassWithStatic::staticVar = 0;int main() {std::cout << "Size of MyClassWithStatic: " << sizeof(MyClassWithStatic) << " bytes" << std::endl; // 4std::cout << "Size of MyClassWithStatic::staticVar: " << sizeof(MyClassWithStatic::staticVar) << " bytes" << std::endl; // 4return 0;
}

10. 联合体

MyComplexUnion 的最大成员是 double,大小为 8 字节

#include <iostream>struct MyStruct {int x;char y;
};union MyComplexUnion {int a;double b;MyStruct c;
};int main() {std::cout << "Size of MyComplexUnion: " << sizeof(MyComplexUnion) << " bytes" << std::endl; // 8std::cout << "Size of int: " << sizeof(int) << " bytes" << std::endl;std::cout << "Size of double: " << sizeof(double) << " bytes" << std::endl;std::cout << "Size of MyStruct: " << sizeof(MyStruct) << " bytes" << std::endl;return 0;
}

11. 结构体使用#program pack

在C++中,结构体的大小不仅取决于其成员的大小,还取决于成员的排列方式和编译器对齐策略。通常情况下,编译器会为结构体的成员添加填充字节,以确保成员在内存中的地址满足对齐要求。

我们可以使用预处理指令#pragma pack来改变编译器的对齐策略,从而影响结构体的大小。比如:#program pack(2),就是按2对齐。

#include <iostream>struct MyStruct {char a; // 1int b; // 4short c; // 2
}; // 4 + 4 = 8#pragma pack(1)
struct MyPackedStruct {char a; // 1int b; // 4short c; // 2
}; // 7
#pragma pack()#pragma pack(2)
struct MyPackedStruct2 {char a; // 1->2int b; // 4short c; // 2
}; // 2 + 4 + 2 = 8
#pragma pack()#pragma pack(4)
struct MyPackedStruct4 {char a; // 1 -> 4int b; // 4short c; // 2 -> 4
}; // 12
#pragma pack()int main() {std::cout << "Size of MyStruct: " << sizeof(MyStruct) << " bytes" << std::endl; // 8std::cout << "Size of MyPackedStruct: " << sizeof(MyPackedStruct) << " bytes" << std::endl; // 7std::cout << "Size of MyPackedStruct2: " << sizeof(MyPackedStruct2) << " bytes" << std::endl; // 8std::cout << "Size of MyPackedStruct4: " << sizeof(MyPackedStruct4) << " bytes" << std::endl; // 12return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/37407.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何用 php 实现邮件发送功能

一、使用 PHPMailer 发送邮件 1、需要先安装 PHPMailer 库。你可以使用 Composer 来安装它&#xff1a; composer require phpmailer/phpmailer2、安装完成后&#xff0c;可以创建一个简单的 PHP 脚本来发送邮件。以下是一个示例脚本&#xff1a; <?php use PHPMailer\P…

RuoYi_Cloud本地搭建

1.进入若依官网获取git地址 &#xff08;1&#xff09;百度搜“若依官网进”入如下界面 &#xff08;2&#xff09;点击进入git&#xff0c;点克隆下载 &#xff08;3&#xff09;复制http地址 2.在git链接在idea本地打开 &#xff08;1&#xff09;返回桌面——右键&#xf…

金属波纹管

金属波纹管是一种外型规则的波浪样的管材&#xff0c;常用的金属波纹管有碳钢的&#xff0c;和不锈钢的&#xff0c;也有钢质衬塑的、铝质的等等。这种管材主要用于需要很小的弯曲半径非同心轴向传动&#xff0c;或者不规则转弯、伸缩&#xff0c;或者吸收管道的热变形等&#…

大数据面试题之HBase(1)

目录 介绍下HBase HBase优缺点 说下HBase原理 介绍下HBase架构 HBase读写数据流程 HBase的读写缓存 在删除HBase中的一个数据的时候&#xff0c;它什么时候真正的进行删除呢?当你进行删除操作&#xff0c;它是立马就把数据删除掉了吗? HBase中的二级索引 HBa…

数据结构历年考研真题对应知识点(数组和特殊矩阵)

目录 3.4数组和特殊矩阵 3.4.2数组的存储结构 【二维数组按行优先存储的下标对应关系(2021)】 3.4.3特殊矩阵的压缩存储 【对称矩阵压缩存储的下标对应关系(2018、2020)】 【上三角矩阵采用行优先存储的应用(2011)】 【三对角矩阵压缩存储的下标对应关系(2016)】 3.4.…

python中Mysql的模糊查询

1.方法一&#xff1a;使用pymysql库的方法 当在Python中使用MySQL进行模糊查询时&#xff0c;我们通常会使用pymysql或mysql-connector-python这样的库来连接MySQL数据库并执行查询。以下是一个使用pymysql进行模糊查询的详细示例&#xff0c;包括安装库、连接数据库、执行查询…

为什么有的手机卡没有语音功能呢?

大家好&#xff0c;今天这篇文章为大家介绍一下&#xff0c;无通话功能的手机卡&#xff0c; 在网上申请过手机卡的朋友应该都知道&#xff0c;现在有这么一种手机卡&#xff0c;虽然是运营商推出的正规号卡&#xff0c;但是却屏蔽了通话功能&#xff0c;你知道这是为什么吗&am…

自组装mid360便捷化bag包采集设备

一、问题一&#xff1a;电脑太重&#xff0c;换nuc 采集mid360数据的过程中&#xff0c;发现了头疼的问题&#xff0c;得一手拿着电脑&#xff0c;一手拿着mid360来采集&#xff0c;实在是累胳膊。因此&#xff0c;网购了一个intel nuc, 具体型号是12wshi5000华尔街峡谷nuc12i…

何时使用查询字符串参数和路径参数_2024-06-28

REST API 已成为构建和使用 Web 服务的标准。在设计 REST API 时&#xff0c;一个重要方面是决定如何构造 URL 和参数。向 API 传递参数的两种常见方法是通过查询字符串参数和路径参数。本文将解释这两种方法之间的区别、何时使用每种方法&#xff0c;并提供示例来说明它们的用…

二刷算法训练营Day45 | 动态规划(7/17)

目录 详细布置&#xff1a; 1. 139. 单词拆分 2. 多重背包理论基础 3. 背包总结 3.1 背包递推公式 3.2 遍历顺序 01背包 完全背包 详细布置&#xff1a; 1. 139. 单词拆分 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单…

昇思25天学习打卡营第6天|linchenfengxue

​​​​​​SSD目标检测 SSD&#xff0c;全称Single Shot MultiBox Detector&#xff0c;是Wei Liu在ECCV 2016上提出的一种目标检测算法。使用Nvidia Titan X在VOC 2007测试集上&#xff0c;SSD对于输入尺寸300x300的网络&#xff0c;达到74.3%mAP(mean Average Precision)以…

刷题Day37|416. 分割等和子集

416. 分割等和子集 题目&#xff1a;416. 分割等和子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;0-1背包问题&#xff0c;重量和价值一样&#xff0c;每个元素只能使用一次&#xff0c;装满背包且最大价值为sum/2就是true 。dp[target] target返回true。 …

nginx架构基本数据结构配置模块请求详解

nginx源码的目录结构&#xff1a; . ├── auto 自动检测系统环境以及编译相关的脚本 │ ├── cc 关于编译器相关的编译选项的检测脚本 │ ├── lib nginx编译所需要的一些库的检测脚本 │ ├── os 与平台相关的一些系统参…

端口扫描攻击检测及防御方案

端口扫描数据一旦落入坏人之手&#xff0c;可能会成为更大规模恶意活动的一部分。因此&#xff0c;了解如何检测和防御端口扫描攻击至关重要。 端口扫描用于确定网络上的端口是否开放以接收来自其他设备的数据包&#xff0c;这有助于网络安全团队加强防御。但恶意行为者也可以…

ubuntu 18 虚拟机安装(5) postgres sql 数据库 简单 应用

ubuntu 18 虚拟机安装&#xff08;5&#xff09; postgres sql 数据库 简单 应用 参考 PostgreSQL的基本使用整理 https://blog.csdn.net/qq_45658339/article/details/124431612 sudo su - postgres psqlsudo -u postgres psqlsudo systemctl status postgresql sudo syste…

50-1 内网渗透 - 未引用的服务路径提权

一、未引用的服务路径介绍 未引用的服务路径(Unquoted Service Path)漏洞利用了Windows文件路径解析的特性。当服务启动时,如果其执行文件路径中包含空格并且未包含在引号中,就可能导致此漏洞的发生。 具体来说,如果完整路径中包含空格且未使用引号括起来,Windows将按顺…

zabbix-server的搭建

zabbix-server的搭建 部署 zabbix 服务端(192.168.99.180) rpm -ivh https://mirrors.aliyun.com/zabbix/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm cd /etc/yum.repos.d sed -i s#http://repo.zabbix.com#https://mirrors.aliyun.com/zabbix# zabbix.r…

实验八 T_SQL编程

题目 以电子商务系统数据库ecommerce为例 1、在ecommerce数据库&#xff0c;针对会员表member首先创建一个“呼和浩特地区”会员的视图view_hohhot&#xff0c;然后通过该视图查询来自“呼和浩特”地区的会员信息&#xff0c;用批处理命令语句将问题进行分割&#xff0c;并分…

【方案+源码】srm供应商招投标管理系统建设方案及源码实现

SRM供应商管理系统功能建设涵盖&#xff1a; 供应商管理&#xff1a;整合供应商信息&#xff0c;实现全生命周期管理。 采购需求管理&#xff1a;精准把握采购需求&#xff0c;优化采购计划。 采购寻源管理&#xff1a;智能寻源&#xff0c;匹配最佳供应商。 采购合同管理&…

TypeScript中的Omit和Pick

最近面试中被问到了TypeScript中的Omit和Pick。第一时间就是尬住了&#xff0c;因为在工作里很少使用了TS&#xff0c;基本都是在写类型。这俩关键词&#xff0c;有点不面熟。面试结束后也是了解了一下&#xff0c;挺简单的两个类型工具。 在 TypeScript 中&#xff0c;Omit 和…