当前位置: 首页 > news >正文

【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,形成无限递归,造成堆栈溢出,系统崩溃.

相关文章:

【C++】总结9

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

C++报错 XX does not name a type;field `XX’ has incomplete type解决方案

C报错 XX does not name a type;field XX’ has incomplete type解决方案 两个C编译错误及解决办法–does not name a type和field XX’ has incomplete type 编译错误一:XX does not name a type 编译错误二:field XX’ has incomplete t…...

28.利用fminsearch、fminunc 求解最大利润问题(matlab程序)

1.简述 1.无约束(无条件)的最优化 fminunc函数 : - 可用于任意函数求最小值 - 统一求最小值问题 - 如求最大值问题: >对函数取相反数而变成求最小值问题,最后把函数值取反即为函数的最大值。 使用格式如下 1.必须预先把函数存…...

图像 检测 - FCOS: Fully Convolutional One-Stage Object Detection (ICCV 2019)

FCOS: Fully Convolutional One-Stage Object Detection - 全卷积一阶段目标检测(ICCV 2019) 摘要1. 引言2. 相关工作3. 我们的方法3.1 全卷积一阶目标检测器3.2 FCOS的FPN多级预测3.3 FCOS中心度 4. 实验4.1 消融研究4.1.1 FPN多级预测4.1.2 有无中心度…...

C# NDArray System.IO.FileLoadException报错原因分析

C# NDArray System.IO.FileLoadException 报错原因分析: 1.NuGet程序包版本有冲突 2.统一项目版本 1.打开解决方案NuGet程序包设置 2.查看是否有版本冲突 3.统一版本冲突...

快速响应,上门维修小程序让您享受无忧生活

随着科技的不断发展和智能手机的普及,上门维修小程序成为了现代人生活中越来越重要的一部分。上门维修小程序通过将维修服务与互联网相结合,为用户提供了更加便捷、高效的维修服务体验。下面将介绍上门维修小程序开发的优势。   提供便捷的预约方式&am…...

05、性能分析思路?

工具操作:包括压力工具、监控工具、剖析工具、调试工具。数值理解:包括上面工具中所有输出的数据。趋势分析、相关性分析、证据链分析:就是理解了工具产生的数值之后,还要把它们的逻辑关系想明白。这才是性能测试分析中最重要的一…...

【编程语言 · C语言 · calloc和realloc】

【编程语言 C语言 calloc和realloc】https://mp.weixin.qq.com/s?__bizMzg4NTE5MDAzOA&mid2247491544&idx1&sn72d8f9931cfa7ce7441a3248475ab619&chksmcfade321f8da6a374a5935bb46441a03a007c0589db6b8afa8c1991854d632a3201553e37b0b&payreadticketHGy…...

机器学习分布式框架ray运行pytorch实例

Ray是一个用于分布式计算的开源框架,它可以有效地实现并行化和分布式训练。下面是使用Ray来实现PyTorch的训练的概括性描述: 安装Ray:首先,需要在计算机上安装Ray。你可以通过pip或conda来安装Ray库。 准备数据:在使用…...

TypeScript 【type】关键字的进阶使用方式

导语: 在前面章节中,我们了解到 TS 中 type 这个关键字,常常被用作于,定义 类型别名,用来简化或复用复杂联合类型的时候使用。同时也了解到 为对象定义约束接口类型 的时候所使用的是 Interfaces。 其实对于前面&#…...

策略路由实现多ISP接入Internet

组网需求&#xff1a; 企业分别从ISP1和ISP2租用了一条链路 PC3用户上网访问Server1时走ISP1PC4用户上网访问Server1时走ISP2 拓扑图 一、ISP1 运营商 R1路由器 <Huawei>sys [Huawei]sys R1 [R1]un in en[R1]int g0/0/0 [R1-GigabitEthernet0/0/0]ip addr 2.2.2.2 2…...

Socket本质、实战演示两个进程建立TCP连接通信的过程

文章目录 Socket是什么引入面试题, 使你更深刻的理解四元组 Socket网络通信大体流程实战演示TCP连接建立过程需要用到的linux 查看网络的一些命令测试的程序一些准备工作启动服务端, 并没有调用accept启动客户端开启服务accept Socket是什么 通俗来说,Socket是套接字,是一种编…...

java学习路程之篇四、进阶知识、石头迷阵游戏、绘制界面、打乱石头方块、移动业务、游戏判定胜利、统计步数、重新游戏

文章目录 1、绘制界面2、打乱石头方块3、移动业务4、游戏判定胜利5、统计步数6、重新游戏7、完整代码 1、绘制界面 2、打乱石头方块 3、移动业务 4、游戏判定胜利 5、统计步数 6、重新游戏 7、完整代码 java之石头迷阵单击游戏、继承、接口、窗体、事件、组件、按钮、图片...

Git全栈体系(三)

第六章 GitHub 操作 一、创建远程仓库 二、远程仓库操作 命令名称作用git remote -v查看当前所有远程地址别名git remote add 别名 远程地址起别名git push 别名 分支推送本地分支上的内容到远程仓库git clone 远程地址将远程仓库的内容克隆到本地git pull 远程库地址别名 远…...

JMeter发送get请求并分析返回结果

在实际工作的过程中&#xff0c;我们通常需要模拟接口&#xff0c;来进行接口测试&#xff0c;我们可以通过JMeter、postman等多种工具来进行接口测试&#xff0c;但是工具的如何使用对于我们来说并不是最重要的部分&#xff0c;最重要的是设计接口测试用例的思路与分析结果的能…...

HTML笔记(1)

介绍 浏览器中内置了HTML的解析引擎&#xff0c;通过解析标记语言来展现网页&#xff1b;HTML标签都是预定义好的&#xff1b;Java工程师&#xff1a;后台代码的编写&#xff0c;和数据库打交道&#xff0c;把数据给网页前端的工程师&#xff1b;网页前端工程师&#xff1a;写H…...

重新审视MHA与Transformer

本文将基于PyTorch源码重新审视MultiheadAttention与Transformer。事实上&#xff0c;早在一年前博主就已经分别介绍了两者&#xff1a;各种注意力机制的PyTorch实现、从零开始手写一个Transformer&#xff0c;但当时的实现大部分是基于d2l教程的&#xff0c;这次将基于PyTorch…...

Docker 全栈体系(七)

Docker 体系&#xff08;高级篇&#xff09; 五、Docker-compose容器编排 1. 是什么 Compose 是 Docker 公司推出的一个工具软件&#xff0c;可以管理多个 Docker 容器组成一个应用。你需要定义一个 YAML 格式的配置文件docker-compose.yml&#xff0c;写好多个容器之间的调…...

【编程范式】聊聊什么是数据类型和范式的本质

什么是编程范式 范式其实就是做事的方式&#xff0c;编程范式可以理解为如何编程&#xff0c;按照什么样的模式或者风格进行编程。 编程范式包含哪些 泛型编程函数式编程面向对象编程编程本质和逻辑编程 虽然有不同的编程范式&#xff0c;但是对于目的来说都是为了解决同一…...

2023-08-01 python根据x轴、y轴坐标(数组)在坐标轴里画出曲线图,python 会调用鼎鼎大名的matlib,用来分析dac 数据

一、python 源码如下 import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt#x[0 ,1,2,3,5,6,10] #y[0,0,3,4,5,7,8]# { 0 , 1 , 0x0003 },// 0 # { 0XFFFF * 1 / 10 , 3006 , 0x0a6b },// 1 # { 0XFFFF * 2 / 10 , 599…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...