动态内存管理-错题合集讲解

 

空指针的解应用操作(错误信息合集)

越界访问

首先我们上一个代码,看看这个的代码的问题 

这个代码的问题显而易见 ,就是在循环里面,产生了越界访问的问题,这里你开辟了10个整形空间,但是从0-10一共是11个整形空间。导致访问不合法的空间,从而导致内存泄露,内存泄露会导致,这个内存一直使用,逐步积累,从而导致内存呗占满。 

——————————————————————————————————————————

free只能释放动态的空间

上面的重点我们说的很清楚,为什么不能让指针移动 

这里我们写上一个代码

指针移动之后 你指的是静态的空间,我们的是什么,我们的函数的动态内存空间的管理。

这里释放的是 p之后的空间

这里 的p不再是动态申请的起始位置

指针跑远了 也就是不指向释放空间了

所以才需要*(p+i)=i+1;

———————————————————————————————————————————

重复释放

也就是两个free

也就不行的

但是你要是 释放之后指向为空指针 那就没有什么问题

重复释放会导致的问题:
1. **不可预知的行为**:

当你重复释放同一块内存时,那个内存区域可能已经被重新分配给了其他用途。如果你再次试图访问它,你可能会读取到未定义的数据,或者更糟糕的是,破坏了其他部分的程序。
2. **内存冲突**:

如果你在释放内存之后又重新分配了相同的大小,并且期望得到相同的内存地址,这是不确定的。每次调用`malloc`或`realloc`都可能返回一个新的内存地址。因此,即使你的代码在逻辑上看起来可以工作,这也是依赖于实现的,并且不应该依赖这种行为。
3. **内存泄漏**:

虽然重复释放内存不会直接导致内存泄漏(因为内存已经被释放),但这通常意味着管理内存不当,可能会导致其他内存泄漏问题。
4. **性能问题**:

在某些情况下,操作系统和内存管理器可能会对重复释放小块内存的行为进行优化,如通过释放和立即重新分配来减少碎片。然而,这取决于具体的实现和配置,不应该依赖于此。
为了避免这些问题,你应该确保每个`malloc`或`realloc`调用都有一个对应的`free`调用,并且只释放一次。一个常用的做法是,在每次调用`malloc`或`realloc`时,都记录下返回的指针,然后在`free`中检查是否是同一个指针,避免重复释放。

———————————————————————————————————————————

忘记释放

导致内存泄露的问题

内存是一种资源 当申请之后不用的时候是需要回收的

其实malloc calloc realloc 申请的内促 如果不想使用 可以使用free释放

如果没有使用free来释放当程序运行结束的时候 也会由操作系统回收的

也就是 一直不退出的话 那个内存别人也用不上

所以 如果申请不释放的话 必须要进行说明

1.谁申请是谁释放------------------malloc free成对出现 --不然就会导致内存泄露的问题 --即使成对出现 也会导致泄露问题

就比如,这里也就是出问题了 即使malloc和free成对出现 也是出现问题了

2.如果不释放 也就是需要告诉使用的人,记得释放

———————————————————————————————————————————

传值调用错题详解(重点)

首先我们来看这个错误代码 

 

首先我们看代码逻辑,首先main函数调用test,test接收的是void类型,设置一个指针变量,指向null,传递给get函数,也就是传递一个空指针给getmemory函数,这个函数接收了,然后进行运算。

接下来我们进行分析代码的错误逻辑。

为什么不取地址是错误的呢,

  1. 传递地址(指针的指针): 当你传递 &strstr 的地址)给函数时,你是在告诉函数你想要操作的是 str 变量的内存地址本身。这允许函数直接修改 str 变量的值,或者使用 str 变量的地址进行其他操作。
  2. 传递指针(不取地址): 当你传递 str(指向 char 的指针)给函数时,你是在告诉函数你想要操作的是 str 指向的字符串。函数可以通过 str 指针访问和修改字符串的内容,但不会直接修改 str 指针本身的值。

这样会导致什么情况呢,就是内存销毁的问题,你这个函数传递的时候,传递的是指针,不是指针的地址。那么此时就会产生一种情况那就是,getmemory函数运算结束,这个函数进行了销毁。

因为他调用结束之后,函数会进行销毁,strcpy函数想拷贝到开辟的空间里面,OK!找不到空间了,因为进行了销毁。

什么意思呢,可以理解为,

张三,有一天忙碌完,不想回家了,在公司楼下开了个酒店住进去了,哎,很不错,告诉李四,我住的209房间特别好,你有空可以去试试。第二天李四也累了,那我也去了,我到地方我就记得209房间,但是张三的209房间已经退房了,那我肯定进不去,我非得进去,那就被保安打一顿。

你这里也是这样,你这里 想拷贝字符创,那可以没问题。关键点在于你这里传递的是数值,他不是地址,那数值的话,函数创建了,然后运行结束进行销毁。你自然找不到房间号。你这里要是传递的是空间的地址,那我可以直接去你的地址进行操作拷贝,你也不需要进行返回什么的,哪怕进行销毁了,那也没事。

1.因为这里传参传递的是数值,函数返回的时候进行了函数的销毁,从而导致非法访问

这里的意思 应该是把100个字节放到str里面去 但是传值调用是不行的 会导致有问题

正确的处理应该是什么呢

我们可以把str取地址,传参传的是地址,然后因为本身str已经是指针,我们采取用二级指针的方式进行接收,也就是指向的是指针的地址,

修改为正确代码1

此时就可以完成任务了 

修改为正确代码2

当然 不喜欢二级指针 也可以进行数值的接受 也就是char*

找个数值进行接收,找个数值进行接收,那就是有返回类型,我们采取的返回类型是char*类型,因为这里是拷贝字符串。接收返回值也是一样的。

提示一下,所以其实不传参也是可以的

图解 

————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

动态管理内存题目详解

举例(传值调用问题)

动态内存管理-传值调用错题解析-CSDN博客

这里给一个代码进行分析

这里的错误很明显,在上面的传值调用问题详解里面,我们说的很清楚,这里我们重新复述一下 ,上面的链接是传址调用链接,我专门列出博客进行说明。可以反复观看

这个代码可能产生的问题是 有可能打印出来 也有可能打印不出来

为什么呢,我们看看代码的逻辑

首先调用函数,创建str,str=null,get调用,数组里面 放一个hello word,这个数组就产生了,此时返回数组,但是这里返回的是p,也就是数组首元素地址。这里返回首元素的地址,但是会产生的的问题就是,函数创建之后会进行销毁,你返回的是首元素的地址,这里空间进行了销毁,这个函数去找的时候,找不到这个地址。

下面进行图解:

假设这个地址 是这个

也就是 当传递数组 这里的空间已经释放

也就是返回的是空指针

也就是 这里是非法访问

当然 如果 空间 没有呗占用的时候 还能打印出来

但是不管有没有在占用 此时也都是非法访问

也就是

函数 这里是创建之后 返回之后 会进行销毁的

也就是销毁之后 这个函数 这个数组销毁了 也就是 有可能被覆盖 也可能不进行覆盖

也就是 这样的情况下 会出现野指针的情况

这里的情况也就是返回栈空间地址的问题

返回就是野指针

——————————————————————————————————————————— 

举例(返回变量问题)

这里也是返回栈空间地址的问题

我们进行逻辑代码的分析

首先我们进入main函数,进入函数里面调用test,用指针p进行接收,然后我们进入test函数,n赋值等于10,此时返回数值。

这里错误就错在返回的是地址,之前我们说到过,地址是会进行销毁的,函数创建之后,返回的时候进行销毁,还是那个找酒店的例子。我们是找不到的。

但是 返回局部变量是可以的

但是 返回局部空间的地址是不可以的 因为地址会进行销毁的

这两句话什么意思呢,就是返回一个数值是可以的,比如返回n,但是返回n的地址是不行的,n是局部变量,局部变量在函数销毁的时候是一并销毁的。

———————————————————————————————————————————

举例(忘记free问题)

这里没有任何问题 但是 唯一的问题 就是没有

free

需要 free一下 指向空指针一下

即使这个程序没有free但是 会自动free

但是 万一程序不退出

那就是大问题

也就是 空间溢出问题,程序一直占用,得不到释放,从而导致内存占用满了,从而导致崩盘。

解决办法就是只需要在最后加上free(str);进行内存空间的释放 

———————————————————————————————————————————

举例(忘记置为空指针问题)

这个代码的问题是, 提前释放

也就是这里拷贝之后就还给操作系统,我们还没有判断和打印,就已经进行销毁创建的空间了,导致的错误

也就是我们没有使用权限了

但是这一块空间 还在

也就是开酒店 虽然你退房了

但是房间还在

但是 虽然我这个空间 还在 但是 我没有使用空间

实际修改代码

也就是 free使用之后,置为空指针 这样后面也就没有什么意义了,这里才是考察的知识点

你也可以修改为这个free放到最后进行释放,这个也是没有问题的 ,但是这个不是我们的考察点。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

爬虫的验证码处理

1.我们先进入chrome浏览器的审查页面找到input方法: 为了不少找到一个input,我们ctrlf的方法输入input来查找 看见我们有6个需要输入的参数。 除了上面几个的input参数,我们还需要获取验证码的图片,后续要将字母填入进去。 二.安…

XDMA windos 编译

1、先安装 Visual Studio 2019 2、Download the Windows Driver Kit (WDK) - Windows drivers | Microsoft Learn 以前的 WDK 版本和其他下载 - Windows 驱动程序 |Microsoft学习 注意版本:下载2004的版本 3、 选择使用10.0.19041.0 安装这个sdk. 先按vs2019 然后…

后端SpringBoot+Mybatis 查询订单数据库奇怪报错加一

排错过程: 看报错意思是SQL语句存在错误,然后使用图形化工具运行这个SQL语句 其实这里稍微细心想一下就能发现问题,但是当时没深入想,就觉得order表前加了数据库名字影响不大,所以感觉SQL语句是没问题的,然…

HarmonyOS实战开发-一次开发,多端部署-视频应用

介绍 随着智能设备类型的不断丰富,用户可以在不同的设备上享受同样的服务,但由于设备形态不尽相同,开发者往往需要针对具体设备修改或重构代码,以实现功能完整性和界面美观性的统一。OpenHarmony为开发者提供了“一次开发&#x…

【Java与数学】若不等式x^2-a*x+a<0的解集中恰有3个整数,求a的范围?

【分析】 既然不等式存在解集,说明一元二次方程x^2-a*xa0有解; 解之间横跨三个整数,说明Δ大于0; 三个整数必然是连续的,因为f(x)x^2-a*xa最多只与x存在两个交点,这是题设里的隐含条件。 【传统解法】 …

2024 3.23~3.29周报

上周工作 SVInvNet论文研读 本周计划 加入DenseNet,修改网络架构,跑代码 总结 DenseNet 密集块:DenseNet将网络分成多个密集块(Dense Block)。在每个密集块内,每一层都连接到前面所有的层。这种跳跃连接有助于解…

Mac m1 Flink的HelloWorld

首先在官方下载Downloads | Apache Flink 下载好压缩包后解压,得到Flink文件夹 进入:cd flink-1.19.0 ls 查看里面的文件: 执行启动集群 ./bin/start-cluster.sh 输出显示它已经成功地启动了集群,并且正在启动 standalonesessio…

Vue ElementPlus Input输入框

Input 输入框 通过鼠标或键盘输入字符 input 为受控组件,它总会显示 Vue 绑定值。 通常情况下,应当处理 input 事件,并更新组件的绑定值(或使用v-model)。否则,输入框内显示的值将不会改变。不支持 v-mode…

Oracle 低代码平台 Apex 最新版本 23.2 安装过程

趁春节快结束前,安装了一把APEX ,到目前为此,APEX最新版本为23.2,23.2和21版本有一些变化,只是用于验证,我 是使用的单独模式,没有安装TOMAT,下面列一下安装过程: 1.环境…

机器学习——最优化模型

最优化模型的概述: 从某种程度上说,我们的世界是由最优化问题组成的。每一天,我们的生活都面临无数的最优化问题:上班怎么选择乘车路线,才能舒服又快速地到达公司;旅游如何选择航班和宾馆,既省…

[flink 实时流基础] 转换算子

flink学习笔记 数据源读入数据之后,我们就可以使用各种转换算子,将一个或多个DataStream转换为新的DataStream。 文章目录 基本转换算子(map/ filter/ flatMap)聚合算子(Aggregation)按键分区(…

【隐私计算实训营006隐语PIR介绍及开发实践】

1. 隐语实现PIR总体介绍 隐匿查询(Private Information Retrieval PIR)定义 按服务器数量分类 单服务器方案(Single Server)多服务器方案(Multi-Server) 按查询类型分类 Index PIRKeyword PIR 隐语目前…

基于两个单片机串行通信的电子密码锁设计

1.功能 电子号码锁在实际应用中应该有两部分,一部分在外部,有键盘部分和密码显示;另一部分内部,设置密码、显示密码。使用单片机自身带有的串口可以很方便的实现单片机之间的通信,使输入的密码值传送到主机检验是否是…

nginx的https与动态负载均衡

nginx的https 证书可以根据你的域名和服务器服务商去进行签发 , 比如 : 阿里云 腾讯云 百度云 华为云等 这里使用的是腾讯云 : 下载证书 : 选择 nginx: 下载之后传递到服务器上。 下面开始配置nginx的https: 1. 解压下载的证书包 cd /etc/ssl unzip xxcc.dwa_nginx.zip mv…

【A-010】基于SSH的宠物狗商城系统(含论文)

【A-010】基于SSH的宠物狗商城系统(含论文) 开发环境: Eclipse/MyEclipse、Tomcat8、Jdk1.8 数据库: MySQL 项目介绍: 在科学技术飞速发展的今天,互联网成为人们快速获取、发布和传递信息的重要渠道&am…

Cesium实现渐变面

一、效果图 二、实现思路 使用着色器,通过纹理坐标和其他参数计算出材质的颜色和透明度。通过给定的颜色、漫反射强度和透明度,计算出最终的反射颜色和透明度,并且根据给定的中心点位置和当前像素的纹理坐标,计算出距离中心的距离…

怎么快速上手虚拟化(容器)技术——以 Docker 为例

Docker 整体介绍 Docker 是一种使用 Go 语言开发的容器工具。所谓容器,实际上是一种虚拟化技术,用于为应用提供虚拟化的运行环境,相较于虚拟机具有轻量级、低延迟的特性。 下面是对上述介绍的说明: 应用程序运行需要一定的依赖…

在 C#和ASP.NET Core中创建 gRPC 客户端和服务器

关于gRPC和Google protobuf gRPC 是一种可以跨语言运行的现代高性能远程过程调用 (RPC) 框架。gRPC 实际上已经成为 RPC 框架的行业标准,Google 内外的组织都在使用它来从微服务到计算的“最后一英里”(移动、网络和物联网)的强大用例。 gRP…

canvas画图,画矩形可拖拽移动,可拖拽更改尺寸大小

提示:canvas画图,画矩形,圆形,直线,曲线可拖拽移动 文章目录 前言一、画矩形,圆形,直线,曲线可拖拽移动总结 前言 一、画矩形,圆形,直线,曲线可拖…

壁纸小程序Vue3(分类页面和用户页面基础布局)

1.配置tabBar pages.json "tabBar": {"color": "#9799a5","selectedColor": "#28B389","list": [{"text": "推荐","pagePath": "pages/index/index","iconPath&quo…