【C++】总结9

文章目录

  • C++从源代码到可执行程序经过什么步骤
  • 静态链接和动态链接
  • 类的对象存储空间
  • C++的内存分区
  • 内存池
  • 在成员函数中调用delete this会出现什么问题?
  • 如果在类的析构函数中调用delete this,会发生什么?

C++从源代码到可执行程序经过什么步骤

  • 预处理:预处理主要是对伪指令和特殊符号进行处理,将.c文件转为.i文件,具体处理如下:
    • 宏定义:如#define Name TockenString等,预编译所要作的是将程序中的全部Name全部用TockenString替换
    • 处理所有的条件编译指令,如#if、#endif、#ifdef等
    • 处理#include预编译指令,将文件内容替换到它的位置,该过程是递归进行的
    • 删除所有的注释//和/**/
    • 保留所有的#pragma编译器指令,编译器需要使用它们
    • 添加行号和文件标识,便于编译时编译器产生调试用的行号信息,该行号也是编译时产生编译错误或警告能够显示行号
  • 编译:经过预处理后的代码进行一系列词法分析、语法分析、语义分析及优化被编译器转换为汇编语言代码。
  • 汇编:将汇编代码转变成机器可以执行的指令(机器码文件)
  • 链接:将不同的源文件产生的目标文件进行链接,从而形成一个可以执行的程序。链接分为静态链接和动态链接

静态链接和动态链接

  • 静态链接和动态链接两者最大的区别在于链接的时机不一样,静态链接是在形成可执行程序前,而动态链接的进行则是在程序执行时

  • 静态链接:

    静态链接是在编译时将程序所需的库文件的代码复制并链接到最终的可执行文件中。在静态链接时,所有用到的库函数的代码都被复制到可执行文件中,使得可执行文件完全独立,不再依赖外部的库文件。这意味着在运行时不需要加载额外的库文件,因此可执行文件的大小较大。

    静态链接的步骤包括编译源代码文件、将对象文件打包成静态库文件(通常以.lib或.a为扩展名),然后将静态库文件链接到最终的可执行文件中。可执行文件中包含了所有用到的库函数的代码,因此可以独立地在任何支持相应系统架构的计算机上运行。

  • 静态链接优缺点:

    优点:代码装载速度快,执行的时候运行速度快

    缺点:一是浪费空间,因为每个可执行程序中对所有需要的目标文件都要有一份副本,所以可能同一个目标文件都在内存存在多个副本;另一方面就是更新比较困难,因为每当库函数的代码修改了,这个时候就需要重新进行编译链接形成可执行程序。

  • 动态链接:

    动态链接是在运行时将程序所需的库文件的代码与程序代码进行动态链接,形成最终的可执行文件。

    动态链接的步骤包括编译源代码文件、将对象文件打包成共享库文件(通常以.dll或.so为扩展名),然后在运行时动态地加载共享库文件,并将程序与共享库连接在一起。

  • 动态链接优缺点:
    优点:节省内存;适用于大规模的软件开发,使开发过程独立、耦合度小,便于不同开发者和开发组织之间进行开发和测试;更新也比较方便,更新时只需要替换原来的目标文件,而无需将所有的程序再重新链接一遍;把链接推迟到了程序运行时,所以每次执行程序都需要进行链接,所以性能会有一定损失。

类的对象存储空间

  • 非静态成员的数据类型大小之和
  • 编译器加入的额外成员变量(如虚表指针)

C++的内存分区

  • 内存可以整体分为三个部分:栈区、堆区、静态常量区。栈区主要存储的是局部变量和函数参数;C语言当中malloc、calloc、realloc、C++当中的new申请的空间基本是在堆区,堆区也被称为自由存储区;静态常量区有两个主要的标记:static定义的变量和字符串常量。静态常量区细分可以是数据段和代码段,全局变量和static变量存放在数据段,字符串常量这种只读常量放在代码段。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-93fw9QOk-1690876395317)(C:\Users\姬新羽\AppData\Roaming\Typora\typora-user-images\image-20230801101015152.png)]

  • 栈又叫堆栈,存储非静态局部变量、函数参数、返回值等等,栈是向下增长的。

  • 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享内存,做进程间通信。

  • 堆用于程序运行时动态内存分配,堆是可以向上增长的。

  • 数据段存储全局数据和静态数据。

  • 代码段存储可执行的代码和只读常量。

内存池

  • 内存池是池化技术的应用之一,池化技术就是程序先向系统申请过量的资源,资源由程序自己来管理,以备不时之需。之所以一次提前申请过量的资源,是因为每次申请该资源都有较大的开销,不如提前申请放着程序自己管理,这样使用的时候就非常方便,大大提高程序的运行效率
  • 内存池是指程序预先从操作系统申请一块足够大的内存,此后,当程序中需要申请内存的时候,不是直接向操作系统申请,而是直接从内存池中获取;同理,当程序释放内存的时候,并不真正将内存返回给操作系统,而是返回内存池。当程序退出(或者特定时间)时,内存池才将之前申请的内存真正释放。
  • 内存池通常是由一块连续的内存区域组成,被划分为大小相等的块或者按照一定的规则进行划分。当需要分配内存时,从内存池中取出一个合适大小的块,当内存不再使用时,将其放回内存池以供后续的再利用。内存池管理者会维护一个空闲块链表,用于记录可用的内存块,这样在分配内存时可以快速找到合适大小的块。
  • 内存池主要解决的问题:提高内存分配的效率,减少了频繁的内存分配和释放操作;内存碎片问题,内存池通过固定大小的块进行内存分配,避免了因为不同大小的内存块交替使用而导致的内存碎片问题;提高程序性能:通过减少内存分配和释放的次数,内存池可以显著提高程序的性能和响应速度。

在成员函数中调用delete this会出现什么问题?

  • delete this 相当于“类对象的自杀”,delete之后,类对象被释放掉,但是只要不涉及到this的指针,任何函数调用都还可以正常进行,为什么呢?
  • 根本原因在于内存模型,在类对象的内存空间中,只有数据成员和虚函数表指针,并不包含类的成员函数,类的成员函数单独放在代码段中。在调用成员函数时,隐含传递一个this指针,告诉成员函数是哪个对象在调用它。
  • 虽然delete之后,类对象被释放掉,在成员函数中调用delete this会出现什么问题?为什么不是指针错误,或者无访问权限令系统崩溃的问题呢?因为释放掉的内存空间并不是立刻被回收的,所以有可能还是可以访问的,只是值是不确定的。当访问或操作数据成员的时候,可能得到一串未初始化的随机数,访问虚函数表,就会出现不可预期的问题。
  • 为什么是不可预期的问题?
  • 上面解释了内存空间并不是马上被回收到系统中,此时这段内存还是可以访问的,但是其中的值却是不确定的,当你获取数据成员,可能得到的是一串很长的未初始化的随机数;访问虚函数表,指针无效的可能性非常高,造成系统崩溃。

如果在类的析构函数中调用delete this,会发生什么?

  • 会导致堆栈溢出。因为delete的本质是“为将被释放的内存调用析构函数,然后,释放内存”。delete this会去调用本对象的析构函数,而析构函数中又调用delete this,形成无限递归,造成堆栈溢出,系统崩溃.

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

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

相关文章

java学习路程之篇六、进阶知识、常用API、Arrays工具类、冒泡排序、选择排序、二分查找、正则表达式

文章目录 1、Arrays工具类2、冒泡排序3、选择排序4、二分查找5、正则表达式 1、Arrays工具类 2、冒泡排序 3、选择排序 4、二分查找 5、正则表达式

【Maven】Nexus3上传maven依赖jar

后端依赖 上次说到前端的批量tgz文件上传私服,其实服务端也有类似情况,我们有个私服也需要进行上传到私服,这里做个记录。因为上次有个小细节没注意白白传错了一遍,这里重新记录总结一下。 # 查看一下结构 $ tree -L 2 . |-- re…

【vue】 Tinymce 富文本编辑器 不想让上传的图片转换成base64,而是链接

前言:最近项目上需要使用富文本编辑器,觉得tinymce很不错就用了,具体怎么在项目中使用参考 【vue】 vue2 中使用 Tinymce 富文本编辑器 【vue】 Tinymce 数据 回显问题 | 第一次正常回显后面,显示空白bug不能编辑 这两天又遇到了…

Windows下RocketMQ的启动

下载地址:下载 | RocketMQ 解压后 一、修改runbroker.cmd 修改 bin目录下的runbroker.cmd set "JAVA_OPT%JAVA_OPT% -server -Xms2g -Xmx2g" set "JAVA_OPT%JAVA_OPT% -XX:MaxDirectMemorySize15g" set "JAVA_OPT%JAVA_OPT% -cp %CLASSP…

八大排序算法--希尔排序(动图理解)

目录 希尔排序 概念 算法思路 动画演示 代码如下 复杂度分析 时间复杂度测试 运行结果 完整代码 创作不易,如果本篇博客对您有一定的帮助,大家记得留言点赞哦。 希尔排序 概念 希尔排序是插入排序的一种,是对直接插入排序的优化。其…

ChinaJoy 2023微星雷鸟17游戏本震撼发布:搭载AMD锐龙9 7945HX首发8499元

ChinaJoy 2023展会中微星笔记本再次给大家带来惊喜,发布了搭载AMD移动端16大核的旗舰游戏本:雷鸟17,更重要的这样一款旗舰性能的游戏本,首发价8499元堪称当今游戏本市场中的“性价比爆款”! 本着和玩家一同制霸游戏战场…

k8s概念-StatefulSet

StatefulSet 是用来管理有状态应用的控制器 StatefulSet 用来管理某Pod集合的部署和扩缩, 并为这些 Pod 提供持久存储和持久标识符StatefulSet | KubernetesStatefulSet 运行一组 Pod,并为每个 Pod 保留一个稳定的标识。 这可用于管理需要持久化存储或稳…

【设计模式——学习笔记】23种设计模式——代理模式Proxy(原理讲解+应用场景介绍+案例介绍+Java代码实现)

介绍 基础介绍 代理模式为一个对象提供一个代理对象,以控制对这个对象的访问。即通过代理对象访问目标对象,这样做的好处是:可以在不修改目标对象代码的基础上,增强额外的功能操作,即扩展目标对象的功能被代理的对象…

牛客网Verilog刷题——VL52

牛客网Verilog刷题——VL52 题目答案 题目 请编写一个十进制计数器模块,当mode信号为1,计数器输出信号递增,当mode信号为0,计数器输出信号递减。每次到达0,给出指示信号zero。模块的接口信号图如下: 模块的…

Flask学习笔记_异步论坛(四)

Flask学习笔记_异步论坛(四) 1.配置和数据库链接1.exts.py里面实例化sqlalchemy数据库2.config.py配置app和数据库信息3.app.py导入exts和config并初始化到app上 2.创建用户模型并映射到数据库1.models/auth.py创建用户模型2.app.py导入模型并用flask-mi…

教师工作量管理系统Springmvc+Spring+Mybatis课程工作量教室java源代码mysql

本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 教师工作量管理系统SpringmvcSpringMybatis 系统有1权…

快速开发人脸识别系统Java版本

简介: 先说下什么是人脸识别系统:举个例子,公司门口有个人脸识别系统,员工站到门口,看着摄像头,大屏幕上会抓拍到你的人脸,然后和公司的员工照片库里的照片比对,比对成功就提示&…

ThreadLocal原理

ThreadLocal原理 ThreadLocal对象new出来存放到堆中,ThreadLocal引用是存放在栈里 Thread 类有个 ThreadLocalMap 成员变量,Map的key是Threadlocal 对象,value是你要存放的线程局部变量。 public void set(T value) {//获取当前线程Thread&…

python爬虫(四)_urllib2库的基本使用

本篇我们将开始学习如何进行网页抓取,更多内容请参考:python学习指南 urllib2库的基本使用 所谓网页抓取,就是把URL地址中指定的网络资源从网络流中读取出来,保存到本地。在Python中有很多库可以用来抓取网页,我们先学习urllib2。…

从零开始学python(十三)爬虫工程师自动化和抓包

前言 回顾之前讲述了python语法编程 必修入门基础和网络编程,多线程/多进程/协程等方面的内容,后续讲到了数据库编程篇MySQL,Redis,MongoDB篇,和机器学习,全栈开发,数据分析,爬虫数…

Go项目实现日志按时间及文件大小切割并压缩

关于日志的一些问题: 单个文件过大会影响写入效率,所以会做拆分,但是到多大拆分? 最多保留几个日志文件?最多保留多少天,要不要做压缩处理? 一般都使用 lumberjack[1]这个库完成上述这些操作 lumberjack //info文件wr…

uniapp实现地图点聚合

点聚合的最重要的一个地方是在 markers 中添加 joinCluster true 这个重要的属性,否则将无法开启点聚合功能。 其实在uniapp的官方文档里体现的不是那么清楚,但是在小程序文档提示的就相当清楚。 实现效果如下: 重点:需要编译在小…

【密码学】四、SM4分组密码算法

SM4分组密码算法 1、概述1.1初始变量算法1.2密钥扩展算法1.3轮函数F1.3.1合成置换T1.3.2S盒 2、算法设计原理2.1非平衡Feistel网络2.2T变换2.2.1非线性变换τ2.2.2线性变换L2.2.3基础置换 2.3密钥扩展算法的设计 1、概述 SM4分组密码算法是一种迭代分组密码算法,采…

SERDES关键技术

目录 一、SERDES介绍 二、SERDES关键技术 2.1 多重相位技术 2.2 线路编解码技术 2.2.1 8B/10B编解码 2.2.2 控制字符(Control Characters) 2.2.3 Comma检测 2.2.4 扰码(Scrambling) 2.2.5 4B/5B与64B/66B编解码技术 2.3 包传…

【C++】-二叉搜索树的详解(递归和非递归版本以及巧用引用)

💖作者:小树苗渴望变成参天大树🎈 🎉作者宣言:认真写好每一篇博客💤 🎊作者gitee:gitee✨ 💞作者专栏:C语言,数据结构初阶,Linux,C 动态规划算法🎄 如 果 你 …