C++对象模型(2)-- 进程内存空间布局

在前面Base类的对象模型中,有base对象实例,虚函数表,静态变量和函数等,这些信息在内存中都有各自的保存位置。了解进程的内存空间布局,比如内存空间分成几大块,各种不同的数据分别保存在内存空间的哪个位置,对深入理解对象模型是非常有帮助的。

1、进程内存空间布局
当把一个可执行文件加载到内存后,就变成了一个进程。
通常进程的内存地址空间可分为以下几个部分:栈、堆、BSS段、数据段、代码段。

1.1 各内存段说明
(1)栈(stack):栈用于存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。
(2)堆(heap):堆用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)。若程序员不释放,则会发生内存泄漏。
(3)bss段(bss segment):通常是指用来存放程序中未初始化的全局变量的一块内存区域。bss段属于静态内存分配。
(4)data段(data segment):通常是指用来存放程序中已初始化的全局变量的一块内存区域。data段属于静态内存分配。
(5)代码段(code segment/text segment):通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

1.2 代码段和数据段的区别
(1)代码段和data段都在可执行文件中,由系统从可执行文件中加载,其内容由程序初始化;而bss段不在可执行文件中,其内容由系统初始化。
(2)bss段并不给该段的数据分配空间,只是记录数据所需空间的大小。而数据段会给数据分配空间,数据保存在目标文件中。

2、内存空间布局的验证

2.1 示例程序的进程空间布局

当分别声明下面2行语句时,其进程空间内存布局是不同的。

Base* pb = nullptr;  
Base* pb = new Base();  

代码验证:

int main() {Base* pb = NULL;printf("print()的地址:%p\n", &(Base::print));printf("print_s()的地址:%p\n", &(Base::print_s));printf("Base::base_s的地址:%p\n", &(Base::base_s));pb->print();pb->print_s();std::cout << pb->base_s << std::endl;
}

估计有读者会感到奇怪,这个pb是NULL,应该报空指针错误啊。

但这个代码是能够正确执行的。而且在编译完成后,多次运行输出的print()、print_s()、base_s地址都是相同的。

为什么呢?

因为一个可执行文件,它的全局变量、全局函数、类静态成员变量等的地址值在编译完成时就已经确定好的,不会发生改变。

成员函数print()、静态函数print_s()和静态变量base_s是跟着类走的,成员函数、静态函数存在代码段,静态变量存在数据段。

下面我们再在main()里添加2行代码:

pb->print_v();
std::cout << pb->base_i << std::endl;

发现这2行代码报错了,我这里用vs2019是提示:pb 是 nullptr。

为什么呢?

非静态成员变量、虚函数指针才会放到对象中。pb是个NULL指针,没指向任何对象,所以在调用其非静态变量base_i、虚函数print_v()时会报nullptr错误。

2.2 变量的存储位置

int bss_1; // 未初始化的全局变量 - bss段
int bss_2 = 0; // 初始化为0的全局变量 - bss段
int data_1 = 1; // 初始化非0的全局变量 - data段int main() {static int bss_3; // 未初始化的静态局部变量 - bss段static int bss_4 = 0; // 初始化为0静态局部变量 - bss段static int data_2 = 1; // 初始化非0静态局部变量,data段printf(" ------ bss段地址 ------\n");printf(" bss_1 = %p\n", &bss_1);printf(" bss_2 = %p\n", &bss_2);printf(" bss_3 = %p\n", &bss_3);printf(" bss_4 = %p\n\n", &bss_4);printf(" ------ data段地址 ------\n");printf(" data_1 = %p\n", &data_1);printf(" data_2 = %p\n", &data_2);return 0;
}

从下面的运行结果可以看到,bss段和data段里数据的存放顺序跟声明顺序是一致的,且data段的地址在bss段的下面。

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

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

相关文章

MyBatisPlus(十一)包含查询:in

说明 包含查询&#xff0c;对应SQL语句中的 in 语句&#xff0c;查询参数包含在入参列表之内的数据。 in Testvoid inNonEmptyList() {// 非空列表&#xff0c;作为参数List<Integer> ages Stream.of(18, 20, 22).collect(Collectors.toList());in(ages);}Testvoid in…

JavaEE初阶学习:HTTP协议和Tomcat

1. HTTP协议 HTTP协议是一个非常广泛的应用层协议~~ 应用层协议 —> TCP IP 协议栈 应用层 —> 关注数据怎么使用~ 传输层 —> 关注的是整个传输的起点和终点 网络层 —> 地址管理 路由选择 数据链路层 —> 相邻节点之间的数据转发 物理层 —> 基础设置,硬…

Jmeter常用参数化技巧总结!

说起接口测试&#xff0c;相信大家在工作中用的最多的还是Jmeter。 JMeter是一个100&#xff05;的纯Java桌面应用&#xff0c;由Apache组织的开放源代码项目&#xff0c;它是功能和性能测试的工具。具有高可扩展性、支持Web(HTTP/HTTPS)、SOAP、FTP、JAVA 等多种协议。 在做…

(六)正点原子STM32MP135移植——内核移植

目录 一、概述 二、编译官方代码 三、移植 四、编译 一、概述 前面已经移植好了TF-A、optee、u-boot&#xff0c;在u-boot能正常跑起来的情况下&#xff0c;现在来移植内核。 二、编译官方代码 进入kernel目录 2.1 解压源码、打补丁 /* 解压源码 */ tar xf linux-6.1.28.…

【网络安全 ---- 靶场搭建】凡诺企业网站管理系统靶场详细搭建过程(asp网站,练习sql注入)

一&#xff0c;资源下载 百度网盘资源下载链接&#xff1a;百度网盘 请输入提取码百度网盘为您提供文件的网络备份、同步和分享服务。空间大、速度快、安全稳固&#xff0c;支持教育网加速&#xff0c;支持手机端。注册使用百度网盘即可享受免费存储空间https://pan.baidu.com…

jira+confluence安装

准备如下所有包&#xff1a; atlassian-agent.jar jdk-8u241-linux-x64.tar.gz atlassian-confluence-8.0.0-x64.bin atlassian-jira-software-9.4.0-x64.bin mysql-8.0.31-1.el8.x86_64.rpm-bundle.tar mysql-connector-java-8.0.28.jar confluence-8.2.1破解 1.安装j…

wpf webBrowser控件 常用的函数和内存泄漏问题

介绍 WebBrowsers可以让我们在窗体中进行导航网页。 WebBrowser控件内部使用ie的引擎&#xff0c;因此使用WebBrowser我们必须安装ie浏览器&#xff08;windows默认安装的&#xff09;。 使用 直接在xmal中使用webBrowser控件 <WebBrowser x:Name"WebBrowser1"…

【用unity实现100个游戏之14】Unity2d做一个建造与防御类rts游戏

文章目录 前言素材新建项目放置物品放置不同物品类型资源管理管理和配置生成资源的信息绘制资源UI同步资源生成绘制地图&#xff0c;优化场景控制虚拟相机添加建筑物按钮UIUI上放置建筑问题修复添加点击事件选中效果箭头空物体效果建造跟随鼠标显示添加资源物体实现树叶的随风摇…

MySQL:主从复制-基础复制(6)

环境 主服务器 192.168.254.1 从服务器&#xff08;1&#xff09;192.168.254.2 从服务器&#xff08;2&#xff09;192.168.253.3 我在主服务器上执行的操作会同步至从服务器 主服务器 yum -y install ntp 我们去配置ntp是需要让从服务器和我们主服务器时间同步 sed -i /…

FFmpeg 命令:从入门到精通 | FFmpeg 解码流程

FFmpeg 命令&#xff1a;从入门到精通 | FFmpeg 解码流程 FFmpeg 命令&#xff1a;从入门到精通 | FFmpeg 解码流程流程图FFmpeg 解码的函数FFmpeg 解码的数据结构补充小知识 FFmpeg 命令&#xff1a;从入门到精通 | FFmpeg 解码流程 本内容参考雷霄骅博士的 FFmpeg 教程。 流…

用min-max容斥实现lcm与gcd互换

lcm本质是每个质因子质数取max&#xff0c;gcd是每个质因子质数取min 然后我们就可以直接套min-max容斥&#xff1a;

unity中绑定动画的行为系统

主要代码逻辑是创建一个action队列,当动画播放结束时就移除队头,执行后面的事件 public class Enemy : MonoBehaviour {public event Action E_AnimatorFin;//当动画播放完毕时public Action DefaultAction;//默认事件public Dictionary<Action, string> EventAnimator n…

Java版工程行业管理系统源码-专业的工程管理软件-提供一站式服务

项目背景 一、随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;公司对内部工程管理的提升提出了更高的要求。 二、企业通过数字化转型&#xff0c;不仅有利于优化业务流程、提升经营管理…

2019年[海淀区赛 第2题] 阶乘

题目描述 n的阶乘定义为n!n*(n -1)* (n - 2)* ...* 1。n的双阶乘定义为n!!n*(n -2)* (n -4)* ...* 2或n!!n(n - 2)*(n - 4)* ...* 1取决于n的奇偶性&#xff0c;但是阶乘的增长速度太快了&#xff0c;所以我们现在只想知道n!和n!!末尾的的个数 输入格式 一个正整数n &#xff…

AI驱动的3D模型无缝纹理生成

创建无缝纹理一直是一个需要艺术技巧的劳动密集型过程。 然而&#xff0c;随着稳定扩散模型&#xff08;Stable Diffusion&#xff09;的出现&#xff0c;情况发生了变化。 通过将文本转换为逼真、无边界的图像&#xff0c;稳定扩散彻底改变了纹理创建&#xff0c;使其变得易于…

Axios、SASS学习笔记

目录 前言 一、Axios基础认识 1、简介 2、相关文档 3、基本配置 4、基础快捷使用 二、Axios封装 1、公共配置文件 2、细化每个接口的配置 3、使用并发送请求 三、SASS 1、简介 2、相关文档 3、使用前奏 4、使用变量 5、嵌套规则 6、父级选择器标识 & 前言…

Leetcode hot 100之二叉树

目录 (反)序列化二叉树&#xff08;str<->tree&#xff09;&#xff1a;前序 前序遍历&#xff08;迭代&#xff09;/路径 stack.length 入栈&#xff1a;中右左 出栈&#xff1a;中左右 中序遍历&#xff08;迭代&#xff09; cur||stack.length 后序遍历&#x…

计算机视觉处理的开源框架

计算机视觉是一门涉及图像和视频分析的领域&#xff0c;有许多开源的框架和库可用于构建计算机视觉应用程序。以下是一些常见的计算机视觉开源框架及其特点&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合…

一盏茶的功夫帮你彻底搞懂JavaScript异步编程从回调地狱到async/await

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 &#x1f4d8; 1. 引言 &#x1f4d8; 2. 使用方法 &#x1f4d8; 3. 实现原理 &#x1f4d8; 4. 写到最后…

Android 自定义PopupWindow,实现下拉框

1、效果图 2、前言 1、页面由 MagicIndicator ViewPager2 Fragment 实现&#xff1b; 2、下拉框是基于WindowManager实现&#xff1b; 3、我使用PopupWindow实现下拉框时&#xff0c;发现一个问题&#xff0c;PopupWindow 在窗口显示的情况下&#xff0c;无法直接从外部修…