【C语言初阶】内存管理(内存的分配方式、常见的内存错误即对策、杜绝”野指针“)_函数造成的内存错误怎么解决-程序员宅基地

技术标签: 算法  c++  C语言  c语言  开发语言  

一、内存的分配方式

二、常见的内存错误及对策

1.使用malloc申请内存后,应该用 if ( p==NULL)或 if ( p! =NULL) 进行防错处理。防止因内存分配失败而使用指针值为 NULL 的内存。

2.如果指向内存块的指针是函数的参数,则在函数的入口处使用assert断言进行检查。

3.不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。

4.避免数组或指针的下标越界,特别要当心发生“多 1 ”或者“少 1”操作。

5.动态内存的申请与释放必须配对,程序中 malloc 与 free 的使用次数一定要相同,防止内存泄漏

6.用 free 释放了内存之后,立即将指针设置为 NULL,防止产生“野指针”。

7.程序中的对象调用关系过于复杂,实在难以搞清楚某个对象究竟是否已经释放了内存,此时应该重新设计数据结构,从根本上解决对象管理的混乱局面。

8.不要返回指向“栈内存”的指针因为该内存在函数体结束时被自动销毁。

三、指针与数组的对比

1.数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。

2.指针可以随时指向任意类型的内存块,它的特征是“可变

3.用运算符sizeof 可以计算出数组的容量(字节数)。但无法计算指针所指的内存容量,除非在申请内存时记住它。

4.注意当数组作为函数的参数进行传递时,该数组会自动退化为同类型的指针。因此,当函数内需用到数组的大小参与计算时,不能在函数内计算数组大小。需要在调用函数之前先使用sizeof计算出数组大小,再将结果作为参数传入函数。

四、free 把指针怎么了?

只是把指针所指的内存给释放掉,但并没有把指针本身干掉。

如果此时不把指针设置为 NULL,那么指针就成了“野指针”

五、杜绝“野指针”

1.初始化指针变量(NULL或有效地址)

2.指针使用之前进行有效性检查

3.如果函数的参数是指针,则在函数的入口处使用assert断言进行有效性检查。

4.指针被 free 释放掉之后,及时设置NULL。

5.注意指针指向的变量的作用范围。例如函数不要返回指向“栈内存”的指针,不要引用另一代码块中的变量地址

六、内存耗尽怎么办?

如果在申请动态内存时找不到足够大的内存块,malloc 和 new 将返回 NULL 指针,宣告内存申请失败。通常有两种方式处理“内存耗尽”问题。

(1)判断指针是否为 NULL,如果是则马上用 return 语句终止本函数。

(2)判断指针是否为 NULL,如果是则马上用  exit (1) 终止整个程序的运行

如果一个函数内有多处需要申请动态内存,那么方式(1)就显得力不从心(释放内存很麻烦),应该用方式(2)来处理。

七、malloc/realloc/free 的使用要点

1.malloc 返回值的类型是 void * ,所以在调用 malloc 时要显式地进行类型转换,将void * 转换成所需要的指针类型。

2.在 malloc 的“( ) ”中使用 sizeof 运算符是良好的风格

3.realloc函数可以对动态开辟的内存的大小进行调整

初次调用realloc效果相当于malloc

不能用存放旧地址的指针接受新空间的地址,如果realloc申请内存失败返回NULL的话,会使指针中的地址丢失,而造成丢失数据

3.free(p) 

如果 p 是NULL指针,那么 free 对 p 无论操作多少次都不会出问题。

如果 p 不是 NULL 指针,那么 free 对 p连续操作两次可能会导致程序运行错误。

如果 p 指向的空间不是动态开辟的,那free函数的行为是未定义的,可能会导致程序运行错误。

如果使用free释放的动态内存块不完整,会造成内存泄露。(不要随意移动指向动态内存空间首地址的指针)

八、柔性数组

柔性数组的特点

1.在C99标准下 ,结构体中的最后一个元素允许是未知大小的数组,这就叫做『柔性数组』成员。

2.结构体中的柔性数组成员前面必须至少有一个其他成员。

3.sizeof 返回的这种结构体大小不包括柔性数组的内存。

4.包含柔性数组成员的结构体用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。

柔性数组的使用

柔性数组的优势

1.方便内存释放:

把结构体的内存以及其成员要的内存一次性分配好

用一次free就可以把所有的内存也给释放掉。

2.有利于提高访问速度

提高访问速度,减少内存碎片

返回专栏目录https://blog.csdn.net/zty857016148/article/details/127068555

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zty857016148/article/details/127066155

智能推荐

【笔记】strftime的使用方法-程序员宅基地

文章浏览阅读5.1k次。strftimestrftime是C语言标准库中用来格式化输出时间的的函数。下面是strftime的用法各参数意义代码使用示例#include<stdio.h>#include<time.h>#define print(s1, s2,s3) \ printf("%-20s%-30s%s\n",s1, s2,s3);int main(){ time_t rawtime; struct tm* timeinfo; char timE[80]; /

2018.09.12 poj3621Sightseeing Cows(01分数规划+spfa判环)-程序员宅基地

文章浏览阅读147次。传送门 01分数规划板题啊。 发现就是一个最优比率环。 这个直接二分+spfa判负环就行了。 代码:#include&lt;iostream&gt;#include&lt;cstdio&gt;#include&lt;cstring&gt;#include&lt;algorithm&gt;#include&lt;cmath&gt;#define N 1005#define...

hive sql的常用日期处理函数总结_hive sql 日期函数-程序员宅基地

文章浏览阅读3.1k次,点赞2次,收藏14次。1)date_format函数(根据格式整理日期)  作用:把一个字符串日期格式化为指定的格式。select date_format('2017-01-01','yyyy-MM-dd HH:mm:ss'); --日期字符串必须满足yyyy-MM-dd格式   结果:2017-01-01 00:00:002)date_add、date_sub函数(加减日期)  作用:把一个字符串日期格式加一天、减一天。select date_add('2019-01-01',1); ..._hive sql 日期函数

Android Studio使用百度语音合成是TTS时报错: ****.so文件找不到的有关问题_旧版的百度语言合成报错-程序员宅基地

文章浏览阅读2.1k次。使用百度语音合成过程时,一直error : notfint libgnustl_shared.so在项目工程gradle文件中添加如下代码段:sourceSets { main { jniLibs.srcDirs = ['libs'] } }..._旧版的百度语言合成报错

BZOJ1202: [HNOI2005]狡猾的商人_狡猾的商人[hnoi2005]-程序员宅基地

文章浏览阅读425次。Description 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的。账本上记录了n个月以来的收入情况,其中第i个月的收入额为Ai(i=1,2,3…n-1,n), 。当 Ai大于0时表示这个月盈利Ai 元,当 Ai小于0时表示这个月亏损Ai元。所谓一段时间内的总收入,就是这段时间内每个月的收入额的总和。 刁姹的任务是秘密进行的,为了调查商人的账本,她只好跑到商人那_狡猾的商人[hnoi2005]

HTML5 Web SQL 数据库_方式准则的定义-程序员宅基地

文章浏览阅读1k次。1、HTML5 Web SQL 数据库 Web SQL 数据库 API 并不是 HTML5 规范的一部分,但是它是一个独立的规范,引入了一组使用 SQL 操作客户端数据库的 APIs。如果你是一个 Web 后端程序员,应该很容易理解 SQL 的操作。Web SQL 数据库可以在最新版的 Safari, Chrome 和 Opera 浏览器中工作。2、核心方法 以下是规范中定义的三个_方式准则的定义

随便推点

如何设置一个计算机用户访问磁盘,登录后限制用户访问硬盘分区-程序员宅基地

文章浏览阅读1.3k次。限制用户登录后访问硬盘分区。我们的部门有一台公用计算机,该计算机由我维护。其他同事也可以偶尔使用它。我在操作系统中为自己创建了一个超级管理员用户,还创建了一个受限用户。登录到计算机后,如何允许受限用户查看但不能访问用于存储重要文件的D分区?您可以通过以下操作实现该目标:在系统桌面上使用鼠标依次选择“开始”。在弹出窗口的“打开”(Open)字段中键入gpedit.msc,然后单击“确定”(OK)按钮..._win7 分区只能某个用户打开

更改vscode Java项目的.class文件输出路径_vscode怎么class文件-程序员宅基地

文章浏览阅读6.7k次,点赞17次,收藏21次。1.在vscode里面按下快捷键ctrl+shift+p2.输入Classpath3.点击Output下的Browse选择.class文件的输出路径4.如图,选择完以后,.class文件的输出层级目录会自动建立_vscode怎么class文件

Python缩进规则-程序员宅基地

文章浏览阅读1.2w次,点赞4次,收藏24次。python的缩进规则:对于类定义、函数定义、流程控制语句、异常处理语句等,行尾的冒号和下一行的缩进,表示下一个代码块的开始,而缩进的结束则表示此代码块的结束。通常情况下都是采用4个空格长度作为一个缩进量(一个Tab键就表示4个空格)。一,Python缩进长度及缩进字符。 看到网上一些Python缩进的错误示范,“tab符和空格不能混用”,“缩进一定是4个空格”下列演示。​def change(a): print(id(a)) # 指向的是同一个对象(tab缩进) a=10_python缩进规则

微信小程序api视频课程-定时器-setTimeout的使用_微信小程序 settimeout 向上层传值-程序员宅基地

文章浏览阅读1.1k次。JS代码 /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { setTimeout( function(){ wx.showToast({ title: '黄菊华老师', }) },2000 ) },说明该代码只执行一次..._微信小程序 settimeout 向上层传值

uploadify2.1.4如何能使按钮显示中文-程序员宅基地

文章浏览阅读48次。uploadify2.1.4如何能使按钮显示中文博客分类:uploadify网上关于这段话的搜索恐怕是太多了。方法多也试过了不知怎么,反正不行。最终自己想办法给解决了。当然首先还是要有fla源码。直接去管网就可以下载。[url]http://www.uploadify.com/wp-content/uploads/uploadify-v2.1.4...

戴尔服务器安装VMware ESXI6.7.0教程(U盘安装)_vmware-vcsa-all-6.7.0-8169922.iso-程序员宅基地

文章浏览阅读9.6k次,点赞5次,收藏36次。戴尔服务器安装VMware ESXI6.7.0教程(U盘安装)一、前期准备1、下载镜像下载esxi6.7镜像:VMware-VMvisor-Installer-6.7.0-8169922.x86_64.iso这里推荐到戴尔官网下载,Baidu搜索“戴尔驱动下载”,选择进入官网,根据提示输入服务器型号搜索适用于该型号服务器的所有驱动下一步选择具体类型的驱动选择一项下载即可待下载完成后打开软碟通(UItraISO),在“文件”选项中打开刚才下载好的镜像文件然后选择启动_vmware-vcsa-all-6.7.0-8169922.iso

推荐文章

热门文章

相关标签