当前位置: 首页 > 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…...

小研究 - 主动式微服务细粒度弹性缩放算法研究(四)

微服务架构已成为云数据中心的基本服务架构。但目前关于微服务系统弹性缩放的研究大多是基于服务或实例级别的水平缩放&#xff0c;忽略了能够充分利用单台服务器资源的细粒度垂直缩放&#xff0c;从而导致资源浪费。为此&#xff0c;本文设计了主动式微服务细粒度弹性缩放算法…...

机器学习深度学习——softmax回归的简洁实现

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——softmax回归从零开始实现 &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习 希望文章对你…...

CPU利用率过高解决思路

文章目录 问题场景问题定位问题解决 本文参考&#xff1a; Linux服务器之CPU过高解决思路_linux cpu温度过高_Jeremy_Lee123的博客-CSDN博客 Java程序员必备&#xff1a;jstack命令解析 - 掘金 (juejin.cn) 重点问题&#xff01;CPU利用率过高排查思路&#xff5c;原创 (qq.…...

Redis(三)—— Redis基本的事务操作、Redis实现乐观锁

一、Redis基本的事务操作 首先声明&#xff1a; redis的单条命令是保证原子性的&#xff08;回想一下setnx k1 v1 k5 v5命令如果k1已经存在&#xff0c;那么k5也会设置失败&#xff09;但是redis的事务不保证原子性&#xff01;见下面“1.2 某条命令有错怎么办&#xff1f;”…...

SQLI_LABS攻击

目录 Less1 首先来爆字段 联合注入 判断注入点 爆数据库名 爆破表名 information_schema information_schmea.tables group_concat() 爆破列名 information_schema.columns 爆值 SQLMAP Less-2 -4 Less -5 布尔 数据库 表名 字段名 爆破值 SQLMAP Less-6 …...

如何查看 Chrome 网站有没有前端 JavaScript 报错?

您可以按照以下步骤在Chrome中查看网站是否存在前端JavaScript报错&#xff1a; 步骤1&#xff1a;打开Chrome浏览器并访问网站 首先&#xff0c;打开Chrome浏览器并访问您想要检查JavaScript报错的网站。 步骤2&#xff1a;打开开发者工具 在Chrome浏览器中&#xff0c;按…...

JS前端读取本地上传的File文件对象内容(包括Base64、text、JSON、Blob、ArrayBuffer等类型文件)

读取base64图片File file2Base64Image(file, cb) {const reader new FileReader();reader.readAsDataURL(file);reader.onload function (e) {cb && cb(e.target.result);//即为base64结果}; }, 读取text、JSON文件File readText(file, { onloadend } {}) {const re…...

【项目方案】OpenAI流式请求实现方案

文章目录 实现目的效果比对非stream模式stream模式实现方案方案思路总体描述前端方案对比event-source-polyfill代码示例前端实现遇到的问题与解决方法后端参考资料时序图关键代码示例后端实现时遇到的问题与解决方法实现目的 stream是OpenAI API中的一个参数,用于控制请求的…...

华为数通HCIP-IP组播基础

点到点业务&#xff1a;比如FTP&#xff0c;WEB业务&#xff0c;此类业务主要特点是不同的用户有不同的需求&#xff0c;比如用户A需要下载资料A&#xff0c;用户B需要下载资料B。此类业务一般由单播承载&#xff0c;服务器对于不同用户发送不同的点到点数据流。 ospf、isis…...

STM32 SPI学习

SPI 串行外设设备接口&#xff08;Serial Peripheral Interface&#xff09;&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线。 SCK时钟信号由主机发出。 SPI接口主要应用在存储芯片。 SPI相关引脚&#xff1a;MOSI&#xff08;输出数据线&#xff…...