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; //4
    double b; //8
};

int main() {
    std::cout << "Size of Base: " << sizeof(Base) << std::endl; // 8
    std::cout << "Size of Derived: " << sizeof(Derived) << std::endl; //8+4+8
    return 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; // 1
    std::cout << "Size of Base: " << sizeof(Base) << std::endl; // 4
    std::cout << "Size of Derived1: " << sizeof(Derived1) << std::endl; // 4 + 8 + 4 = 16
    std::cout << "Size of Derived2: " << sizeof(Derived2) << std::endl; // 4 + 8 + 4 = 16
    std::cout << "Size of Final: " << sizeof(Final) << std::endl; // 8 + 8 + 4 + 4 + 4 + 4 = 32
    return 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; // 4
    double b; // 8
    char c; // 1 -> 4
};

class MyClass {
public:
    int x; // 4
    float y; // 4
    char z; // 1 -> 4
};

int main() {
    std::cout << "Size of MyStruct: " << sizeof(MyStruct) << " bytes" << std::endl; // 对齐后16
    std::cout << "Size of MyClass: " << sizeof(MyClass) << " bytes" << std::endl; // 对齐后 12
    return 0;
}

5. 数组

#include <iostream>

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

6. 类型别名

#include <iostream>

typedef int MyInt;
typedef double MyDouble;

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

7. 动态分配内存

#include <iostream>

int main() {
    int* ptr = new int[10];
    std::cout << "Size of pointer to int[10]: " << sizeof(ptr) << " bytes" << std::endl; // 8
    std::cout << "Size of dynamically allocated int[10]: " << sizeof(*ptr) * 10 << " bytes" << std::endl; // 4 * 10 = 40
    delete[] 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; // 8
    std::cout << "Size of int pointer: " << sizeof(intPtr) << " bytes" << std::endl; // 8
    std::cout << "Size of double pointer: " << sizeof(doublePtr) << " bytes" << std::endl; // 8
    return 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; // 4
    std::cout << "Size of MyClassWithStatic::staticVar: " << sizeof(MyClassWithStatic::staticVar) << " bytes" << std::endl; // 4
    return 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; // 8
    std::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; // 1
    int b; // 4
    short c; // 2
}; // 4 + 4 = 8

#pragma pack(1)
struct MyPackedStruct {
    char a; // 1
    int b; // 4
    short c; // 2
}; // 7
#pragma pack()

#pragma pack(2)
struct MyPackedStruct2 {
    char a; // 1->2
    int b; // 4
    short c; // 2
}; // 2 + 4 + 2 = 8
#pragma pack()

#pragma pack(4)
struct MyPackedStruct4 {
    char a; // 1 -> 4
    int b; // 4
    short c; // 2 -> 4
}; // 12
#pragma pack()

int main() {
    std::cout << "Size of MyStruct: " << sizeof(MyStruct) << " bytes" << std::endl; // 8
    std::cout << "Size of MyPackedStruct: " << sizeof(MyPackedStruct) << " bytes" << std::endl; // 7
    std::cout << "Size of MyPackedStruct2: " << sizeof(MyPackedStruct2) << " bytes" << std::endl; // 8
    std::cout << "Size of MyPackedStruct4: " << sizeof(MyPackedStruct4) << " bytes" << std::endl; // 12
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

firewalld防火墙转发流量到其他端口forward port rules

假设云主机eth0: 47.93.27.106 tun0: inet 10.8.0.1 netmask 255.255.255.0 Show rules for a specific zone (public) sudo firewall-cmd --zonepublic --list-all Add the tun0 interface to the public zone: sudo firewall-cmd --zonepublic --add-interfacetun0 --…

关于图片大小问题造成的QPixmap或QImage读取图片失败的解决办法

今天碰到一个奇怪又离谱的问题 : 图片加载失败。明明路径是正确的&#xff0c;图片也实实在在存在。。。 经过比对&#xff0c;发现如下问题&#xff1a; 我就齐了怪了 这大小怎么差这么多&#xff1f;会不会是这里除了问题。秉持着怀疑的态度&#xff0c;我试着用GIMP重新导出…

机械设计简单介绍

机械设计简单介绍 1 介绍1.1 概述1.2 机械机构设计基本步骤1.3 关键1.3.1 静力学1.3.2 动力学1.3.3 运动学1.3.4 刚度学 1.4 示例【机械臂】 2 资料2.1 知识体系2.2 博客类汇总2.3 免费CAD模型获取2.4 3D打印2.5 SolidWorks 3 具备能力3.1 熟练翻阅 机械设计手册3.2 知道 N 家常…

【01-02】Mybatis的配置文件与基于XML的使用

1、引入日志 在这里我们引入SLF4J的日志门面&#xff0c;使用logback的具体日志实现&#xff1b;引入相关依赖&#xff1a; <!--日志的依赖--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version&g…

Part 8.3.3 最近公共祖先

两个点的最近公共祖先&#xff0c;即两个点的所有公共祖先中&#xff0c;离根节点最远的一个节点。 【模板】最近公共祖先&#xff08;LCA&#xff09; 题目描述 如题&#xff0c;给定一棵有根多叉树&#xff0c;请求出指定两个点直接最近的公共祖先。 输入格式 第一行包含…

VMware虚拟机安装CentOS7.9 Oracle 11.2.0.4 RAC+单节点RAC ADG

目录 一、参考资料 二、RAC环境配置清单 1.主机环境 2.共享存储 3.IP地址 4.虚拟机 三、系统参数配置 1. 配置网卡 1.1 配置NAT网卡 1.2 配置HostOnly网卡 2. 修改主机名 3. 配置/etc/hosts 4. 关闭防火墙 5. 关闭Selinux 6. 配置内核参数 7. 配置grid、oracle…

vue3:星星评分组件

一、效果 二、代码 子组件stars.vue&#xff1a; <template><div class"stars"><div class"star" v-for"star in stars" :key"star" click"setScore(star)"><svgt"1719659437525"class&qu…

贪心算法题目总结

1. 整数替换 看到这道题目&#xff0c;我们首先能想到的方法就应该是递归解法&#xff0c;我们来画个图 此时我们出现了重复的子问题&#xff0c;就可以使用递归&#xff0c;只要我们遇到偶数&#xff0c;直接将n除以2递归下去&#xff0c;如果是奇数&#xff0c;选出加1和减1中…

面试框架一些小结

springcloud的⼯作原理 springcloud由以下⼏个核⼼组件构成&#xff1a; Eureka&#xff1a;各个服务启动时&#xff0c;Eureka Client都会将服务注册到Eureka Server&#xff0c;并且Eureka Client还可以反过来从Eureka Server拉取注册表&#xff0c; 从⽽知道其他服务在哪⾥ …

Java+JSP+Mysql+Tomcat实现Web图书管理系统

简介&#xff1a; 本项目是基于springspringmvcJdbcTemplate实现的图书馆管理系统&#xff0c;包含基本的增删改查功能&#xff0c;可作为JavaWeb初学者的入门学习案例。 环境要求&#xff1a; java8 mysql5.7及以下 eclipse最新版 项目目录 模块设计 页面设计 1. 登录页…

【Spring Boot】认识 JPA 的接口

认识 JPA 的接口 1.JPA 接口 JpaRepository2.分页排序接口 PagingAndSortingRepository3.数据操作接口 CrudRepository4.分页接口 Pageable 和 Page5.排序类 Sort JPA 提供了操作数据库的接口。在开发过程中继承和使用这些接口&#xff0c;可简化现有的持久化开发工作。可以使 …

汽车尾灯(转向灯)电路设计

即当汽车进行转弯时,司机打开转向灯,尾灯会根据转向依次被点亮,经过一定的间隔后,再全部被消灭。不停地重复,直到司机关闭转向灯。 该效果可由以下电路实现: 完整电路图: 02—电路设计要点 延时电路的要点主要有两个: 一、当转向开关被按下时,LED需要逐个亮起; 二、LED被逐…

【AI编译器】triton学习:编程模型

介绍 动机 在过去十年里&#xff0c;深度神经网络 (DNNs) 已成为机器学习 (ML) 模型的一个重要分支&#xff0c;能够实现跨领域多种应用中的最佳性能。这些模型由一系列包括参数化&#xff08;如滤波器&#xff09;和非参数化&#xff08;如缩小值函数&#xff09;元件组成的…

STM32 HAL库里 串口中断回调函数是在怎么被调用的?

跟着正点原子学习的HAL库写串口接收程序的时候一直有困惑&#xff0c;使用HAL_UART_Receive_IT开启接收中断后&#xff0c;为啥处理函数要写在HAL_UART_RxCpltCallback里&#xff0c;中断发生的时候是怎么到这个回调函数里去的&#xff1f; void MX_USART1_UART_Init(void) {h…

x-api-eid-token参数分析与加密算法还原

文章目录 1. 写在前面2. 接口分析3. 算法实现 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python…

操作符详解(下) (C语言)

操作符详解下 操作符的属性1.优先级2.结合级 表达式求值1.整型提升2.如何进行整形提升呢&#xff1f;3.算术转换4.问题表达式解析 操作符的属性 C语言的操作符有2个重要的属性&#xff1a;优先级、结合性&#xff0c;这两个属性决定了表达式求值的计算顺序。 1.优先级 优先级…

【操作系统期末速成】 EP04 | 学习笔记(基于五道口一只鸭)

文章目录 一、前言&#x1f680;&#x1f680;&#x1f680;二、正文&#xff1a;☀️☀️☀️2.1 考点七&#xff1a;进程通信2.2 考点八&#xff1a;线程的概念2.3 考点九&#xff1a;处理机调度的概念及原则2.4 考点十&#xff1a;调度方式与调度算法 一、前言&#x1f680;…

DM 的断点续传测试

作者&#xff1a; 大鱼海棠 原文来源&#xff1a; https://tidb.net/blog/4540ae34 一、概述 DM有all、full、incremental三种数据迁移同步方式&#xff08;task-mode&#xff09;&#xff0c;在all同步模式下&#xff0c;因一些特殊情况&#xff0c;需要变更上游MySQL的数…

【解释】i.MX6ULL_IO_电气属性说明

【解释】i.MX6ULL_IO_电气属性说明 文章目录 1 Hyst1.1 迟滞&#xff08;Hysteresis&#xff09;是什么&#xff1f;1.2 GPIO的Hyst. Enable Field 参数1.3 应用场景 2 Pull / Keep Select Field2.1 PUE_0_Keeper — Keeper2.2 PUE_1_Pull — Pull2.3 选择Keeper还是Pull 3 Dr…

Coursera耶鲁大学金融课程:Financial Markets 笔记Week 03

Financial Markets 本文是学习 https://www.coursera.org/learn/financial-markets-global这门课的学习笔记 这门课的老师是耶鲁大学的Robert Shiller https://en.wikipedia.org/wiki/Robert_J._Shiller Robert James Shiller (born March 29, 1946)[4] is an American econom…