C++内存布局

温故而知新,本文浅聊和回顾下C++内存布局的知识。

一、c++内存布局

C++的内存布局主要包括以下几个部分:

  • 代码段:存储程序的机器代码。
  • .数据段:存储全局变量和静态变量。数据段又分为初始化数据段(存储初始化的全局变量和静态变量)和未初始化数据段(存储未初始化的全局变量和静态变量)。
  • :用于动态内存分配。当你使用new或malloc函数时,内存会从堆中分配。
  • :用于存储局部变量和函数调用的信息(例如返回地址和参数)。当你调用一个函数时,一个新的栈帧会被压入栈,当函数返回时,这个栈帧会被弹出。
  • 常量段:存储常量字符串和其他常量。

代码示例

#include <iostream>int global_var = 0;  // 初始化的全局变量,存储在初始化数据段
int uninit_global_var;  // 未初始化的全局变量,存储在未初始化数据段void foo() {int local_var = 0;  // 局部变量,存储在栈static int static_local_var = 0;  // 静态局部变量,存储在初始化数据段int* dynamic_var = new int(0);  // 动态分配的内存,地址在堆,dynamic_var指针变量的生命周期是foo函数栈std::cout << "local_var: " << &local_var << std::endl;std::cout << "static_local_var: " << &static_local_var << std::endl;std::cout << "dynamic_var: " << dynamic_var << std::endl;delete dynamic_var;  // 释放动态分配的内存
}int main() {std::cout << "global_var: " << &global_var << std::endl;std::cout << "uninit_global_var: " << &uninit_global_var << std::endl;foo();return 0;
}

二、C++ 类的内存布局

C++类的内存布局主要取决于类的数据成员和继承关系。以下是一些基本的规则:

  • 数据成员变量:类的数据成员按照它们在类定义中的顺序存储在内存中。每个数据成员的偏移量是它的类型对齐要求的倍数。
// x64
#pragma pack(push,4) //指定4字节对齐
class TmpClass{}; // 空类sizeof,大小为1class NoVirtual
{
public:int m_i;    // 4字节double m_d; // 8字节shared_ptr<int> m_ptr; // 8字节 ==》64bit system ;4字节 ==》 32bit system
};
#pragma pack(pop) 
  • 成员函数:在C++中,成员函数并不直接存储在每个对象中。相反,所有对象共享同一个成员函数的副本。成员函数的代码存储在代码段,而不是每个对象的内存空间。因此,成员函数不影响类的sizeof大小。
    当你调用一个对象的成员函数时,编译器会自动将对象的地址作为隐藏参数传递给成员函数。这个隐藏参数通常被称为this指针。通过this指针,成员函数可以访问调用它的对象的数据成员。
class NoVirtual
{void dc(){}	// 成员函数,内存在代码段
public:int m_i;    // 4字节double m_d; // 8字节shared_ptr<int> m_ptr; // 8字节 ==》64bit system ;4字节 ==》 32bit system
};
  • 静态成员变量:静态成员变量不属于类的任何一个对象,它们在所有对象之间共享。静态成员变量存储在全局数据段,而不是对象的内存空间。

  • 静态成员函数:静态成员函数也不属于类的任何一个对象。它们没有this指针,因此不能访问类的非静态成员。静态成员函数的地址存储在代码段。

  • 继承:如果一个类继承自一个或多个基类,那么基类的数据成员会先于派生类的数据成员存储在内存中。如果有多个基类,那么基类的数据成员按照它们在类定义中的顺序存储。

class Iface
{
public:Iface(){MYTRACE();}virtual ~Iface(){MYTRACE();}virtual void Ifun() = 0;
};// 继承
class MemLayout : public Iface
{
public:MemLayout(){ MYTRACE(); }~MemLayout(){ MYTRACE(); }virtual void Ifun() override { MYTRACE(); }virtual void dc0(){ MYTRACE(); }virtual void dc1(){ MYTRACE(); }private:int m_num = 0;static std::string m_desc;
};std::string MemLayout::m_desc = "hello";

在这里插入图片描述

  • 虚函数:如果一个类有虚函数(virtual关键字修饰),那么编译器会为这个类生成一个虚函数表(vtable: 函数指针数组),并在每个对象中添加一个指向虚函数表的指针(vptr)。虚函数表中存储了虚函数的地址。如果一个类继承自一个有虚函数的基类,那么它会继承基类的虚函数表。
class VirtualClass
{virtual  void dc(){}
public:int m_i;    // 4字节double m_d; // 8字节shared_ptr<int> m_ptr; // 8字节 ==》64bit system ;4字节 ==》 32bit system
};

在这里插入图片描述

  • 虚继承:如果一个类使用虚继承,那么编译器会为这个类生成一个虚基类表(vbtable),并在每个对象中添加一个指向虚基类表的指针。虚基类表中存储了虚基类的偏移量。直白点说,虚继承的派生类的实例化对象,可是唯一指向了两张虚函数表的(下面有图为证)~
    请添加图片描述
class NoVirtual
{void dc(){}
public:int m_i;    // 4字节double m_d; // 8字节shared_ptr<int> m_ptr; // 8字节 ==》64bit system ;4字节 ==》 32bit system
};class Iface
{
public:Iface(){MYTRACE();}virtual ~Iface(){MYTRACE();}virtual void Ifun() = 0;
};// 虚继承
class MemLayout : virtual public Iface
{
public:MemLayout(){ MYTRACE(); }~MemLayout(){ MYTRACE(); }virtual void Ifun() override { MYTRACE(); }virtual void dc0(){ MYTRACE(); }virtual void dc1(){ MYTRACE(); }private:int m_num = 0;static std::string m_desc;
};std::string MemLayout::m_desc = "hello";

在这里插入图片描述

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

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

相关文章

python与机器学习2,激活函数

目录 1 什么是激活函数&#xff1f; activation function 1.1 阈值 1.2 激活函数a(x) &#xff0c;包含偏置值θ 1.3 激活函数a(x) &#xff0c;包含偏置值b 2 激活函数1: 单位阶跃函数 2.1 函数形式 2.2 函数图形 2.3 函数特点 2.4 代码实现这个 单位阶跃函数 3 激活…

Convolutional Neural Network(CNN)——卷积神经网络

1.NN的局限性 拓展性差 NN的计算量大性能差&#xff0c;不利于在不同规模的数据集上有效运行若输入维度发生变化&#xff0c;需要修改并重新训练网络容易过拟合 全连接导致参数量特别多&#xff0c;容易过拟合如果增加更多层&#xff0c;参数量会翻倍无法有效利用局部特征 输入…

结构型设计模式(三)享元模式 代理模式 桥接模式

享元模式 Flyweight 1、什么是享元模式 享元模式的核心思想是共享对象&#xff0c;即通过尽可能多地共享相似对象来减少内存占用或计算开销。这意味着相同或相似的对象在内存中只存在一个共享实例。 2、为什么使用享元模式 减少内存使用&#xff1a;通过共享相似对象&#…

汽车UDS诊断——SecureDataTransmission 加密数据传输(0x84)

诊断协议那些事儿 诊断协议那些事儿专栏系列文章,本文介绍诊断和通讯管理功能单元下的84服务SecureDataTransmission,在常规诊断通信中,数据极易被第三方获取,所以在一些特殊的数据传输时,标准定义了加密数据传输的服务。 简而言之,就是在发送诊断数据时,发送方先把数…

fragstats:景观指数的时间序列分析框架

作者&#xff1a;CSDN _养乐多_ 本文将介绍景观指数的时间序列分析计算的软件使用方法和 python 代码&#xff0c;该框架可用于分析景观指数时间序列图像的趋势分析、突变分析、机器学习&#xff08;分类/聚类/回归&#xff09;、相关性分析、周期分析等方面。 文章目录 一、…

智能优化算法应用:基于人工电场算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于人工电场算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于人工电场算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.人工电场算法4.实验参数设定5.算法结果6.…

04-Revision和流量管理

1 Revision 关于Revision 应用程序代码及相关容器配置某个版本的不可变快照KService上的spec.template的每次变动&#xff0c;都会自动生成一个新的Revision通常不需要手动创建及维护 Revision的使用场景 将流量切分至不同版本的应用程序间&#xff08;Canary Deployment、Blu…

静态路由及动态路由

文章目录 静态路由及动态路由一、静态路由基础1. 静态路由配置2. 负载分担3. 路由备份4. 缺省路由5. 静态路由实操 二、RIP 动态路由协议1. RIP 协议概述2. RIP 协议版本对比2.1 有类路由及无类路由 3. RIP 路由协议原理4. RIP 计时器5. 度量值6. 收敛7. 示例 静态路由及动态路…

Kafka基本原理及使用

目录 基本概念 单机版 环境准备 基本命令使用 集群版 消息模型 成员组成 1. Topic&#xff08;主题&#xff09;&#xff1a; 2. Partition&#xff08;分区&#xff09;&#xff1a; 3. Producer&#xff08;生产者&#xff09;&#xff1a; 4. Consumer&#xff08;…

使用TensorRT对Yolov5进行部署【基于Python】

如果还未配置TensorRT&#xff0c;请看这篇博文&#xff1a;Win11下TensorRT环境部署 这里使用TensorRT对Yolov5进行部署流程比较固定&#xff1a;先将pt模型转换为onnx&#xff0c;再将onnx模型转为engine&#xff0c;所以在执行export.py时要将onnx、engine给到include。 P…

Linear Regression线性回归(一元、多元)

目录 介绍&#xff1a; 一、一元线性回归 1.1数据处理 1.2建模 二、多元线性回归 2.1数据处理 2.2数据分为训练集和测试集 2.3建模 介绍&#xff1a; 线性回归是一种用于预测数值输出的统计分析方法。它通过建立自变量&#xff08;也称为特征变量&#xff09;和因变…

【Redis】五、Redis持久化、RDB和AOF

文章目录 Redis持久化一、RDB&#xff08;Redis DataBase&#xff09;触发机制如何恢复rdb文件 二、AOF&#xff08;Append Only File&#xff09;三、扩展 Redis持久化 面试和工作&#xff0c;持久化都是重点&#xff01; Redis 是内存数据库&#xff0c;如果不将内存中的数据…

微服务实战系列之ZooKeeper(实践篇)

前言 关于ZooKeeper&#xff0c;博主已完整的通过庖丁解牛式的“解法”&#xff0c;完成了概述。我想掌握了这些基础原理和概念后&#xff0c;工作的问题自然迎刃而解&#xff0c;甚至offer也可能手到擒来&#xff0c;真实一举两得&#xff0c;美极了。 为了更有直观的体验&a…

uniapp 预览图片

preImg(index){let urls []this.images.map((item,i) > {if(indexi){urls.unshift(item.file_path)}else{urls.push(item.file_path)}})uni.previewImage({urls})}

linux之Samba服务器

环境&#xff1a;虚拟机CENTOS 7和 测试机相通 一、Samba服务器_光盘共享&#xff08;匿名访问&#xff09; 1.在虚拟机CENTOS 7安装smb服务&#xff0c;并在防火墙上允许samba流量通过 2. 挂载光盘 3.修改smb.conf配置文件&#xff0c;实现光盘匿名共享 4. 启动smb服务 5.在…

JVM基础扫盲

什么是JVM JVM是Java设计者用于屏蔽多平台差异&#xff0c;基于操作系统之上的一个"小型虚拟机"&#xff0c;正是因为JVM的存在&#xff0c;使得Java应用程序运行时不需要关注底层操作系统的差异。使得Java程序编译只需编译一次&#xff0c;在任何操作系统都可以以相…

英码科技受邀参加2023计算产业生态大会,分享智慧轨道交通创新解决方案

12月13-14日&#xff0c;“凝心聚力&#xff0c;共赢计算新时代”——2023计算产业生态大会在北京香格里拉饭店成功举办。英码科技受邀参加行业数字化分论坛活动&#xff0c;市场总监李甘来先生现场发表了题为《AI哨兵&#xff0c;为铁路安全运营站好第一道岗》的精彩主题演讲&…

1951 年以来的美国ACIS 气候地图数据集(5 公里空间分辨率)

应用气候信息系统 (ACIS) NRCC NN ACIS是Applied Climate Information System的缩写&#xff0c;是由美国国家气象局&#xff08;NOAA&#xff09;开发的一种气候信息系统。ACIS气候地图是通过收集和整理全球的气象数据&#xff0c;利用计算机技术和数据分析方法生成的气候图表…

计算机组成原理-选择语句和循环语句的汇编表示

文章目录 选择语句jmpjxx示例&#xff1a;选择语句的机器级表示扩展&#xff1a;cmp指令的底层原理 循环语句使用条件转移指令实现循环用loop指令实现循环 选择语句 不一定知道指令的位置&#xff0c;所以jmp直接跳转到指令的位置很难办 jmp 标号相当于位置&#xff0c;名字…

解决win11杀毒(不能安装破解软件的问题)

1、下载火绒APP&#xff0c;打开火绒APP软件 2、点击菜单&#xff0c;选择安全设置 3、选择病毒防护&#xff0c;修改病毒处理方式为询问我 4、这样在解压激活的软件就不会被windows的杀毒软件自动删除了 5、问题解决了就点击三连吧