"迷途"的野指针,都快找不着北了
指针,C语言开发者表示很淦,指针的使用,很多人表示不敢直面ta,不像Java一样,有垃圾自动回收功能,我们不用担心那么多内存泄漏等问题,那C语言里边呢,指针又分为了"野指针","迷途指针" 。 你是不是更迷糊了,这篇一起来攻克ta!
- 发现我的封面似乎致敬了一下路痴"索隆",刚好跟我们今天的主角一样,找不着北的"迷途"指针hhh
悬垂指针/迷途指针定义
- 当所指向的对象被释放或者收回,但是对该指针没有作任何的修改,以至于该指针仍旧指向已经回收的内存地址,此情况下该指针便称悬垂指针(也叫迷途指针)。
野指针定义
- 野指针指的是还没有初始化的指针(导致我们不知道他会指向哪里)
int* p;
//没有初始化就使用他
printf("%p", p);
编译器一般会提示你出错了!
常见错误:
1。指针定义时未被初始化:
- 指针在被定义的时候,如果程序不对其进行初始化的话,它会随机指向一个区域 。
这种指针就是我们上边所说的野指针
//先定义一个指针(没有初始化)
int *p ;
//然后就使用这个指针
*p =12;
2。指针释放后没有置空:
- 我们在用malloc()开辟空间的时候,要检查返回值是否为空
- 如果为空,则开辟失败;
- 如果不为空,则指针指向的是开辟的内存空间的首地址。
- 指针指向的内存空间在用free()或delete释放后,此时指针指向的就是“垃圾”内存。如果我们没有对其进行置空或者其他赋值操作的话,就有可能会成为悬垂指针/迷途指针 。
free
free() 只能释放动态分配的内存空间,并不能释放任意的内存。下面的写法是错误的:
int a[10];
free(a);
注意:free() 不会改变 np 变量(一个指向结构体的指针)本身的值,调用 free() 后它仍然会指向相同的内存空间
可以把他理解为,原本np指向了一个房子,现在free了,把房子里的人赶了出去,而np仍然指向这个房子
但是此时该内存已无效,不能被使用。
把他们打印出来的话还是一样的,但是再访问的话
free之后访问到的数据就奇奇怪怪的了
规避方法
建议在 free操作后 将 np 的值设置为 NULL,例如:
free(np);
np=NULL;
3。在方法中定义变量,返回该变量的地址
- 先来看一个实例
#include"stdio.h"
int* tempAddress() {
int temp1[] = { 1,2,3 };
return temp1;
}
int* tempAddress2() {
int temp2[] = { 4,5,6 };
return temp2;
}
int main() {
//第一次
int* temp = tempAddress();
printf("%d\n", *temp);
//调用另一个完全不一样的函数
tempAddress2();
//重新输出
printf("%d\n", *temp);
}
诶?明明第一次还能输出出来来着,怎么后边调用了另一个完全不一样的函数之后就输出变得那么奇怪了呢?
栈
- 要知道,我们每个方法执行的时候,都会为这个方法去分配一个栈帧,当这个函数返回时,为栈帧分配的那一块内存区域可能就已经被释放了,但是数据还未清理
- 但是任何接下来的函数调用都可能又会把刚才释放掉的那块空间给占用了。导致再输出temp所指向的值时,就变成我们新修改的值了
堆
可能看到这里有的同学会有疑问了?诶,那free跟这个方法栈的回收有什么区别呢?为什么free过后是直接不能访问呢,而方法栈的回收却只是把区域回收了,但是数据还没有清理掉
其实我们free,通常都是搭配malloc来使用的,何谓malloc,malloc是我们程序员手动在堆中开辟一个空间,可以自己进行管理,不会像栈一样,出了函数就自动被回收了
来看我们用malloc能不能解决上边那个问题
int* tempAddress() {
//int a[] = { 1,2,3 };
int* a = (int*)malloc(sizeof(int) * 3);
a[0] = 1;
return a;
}
int* tempAddress2() {
//int b[] = { 4,5,6 };
int* b = (int*)malloc(sizeof(int) * 3);
b[0] = 4;
return b;
}
int main() {
int* temp = tempAddress();
printf("%d\n", *temp);
tempAddress2();
printf("%d\n", *temp);
- 是不是美滋滋,我们可以自己手动控制这块区域了,要回收也是我们自己回收,不会说出了函数体就被自动回收了
堆栈需要注意的问题
内存空间不足,内存泄漏
malloc一时爽,一直malloc一直爽,随着我们开发不断的malloc,可能会带来什么问题呢?
- 最显而易见的当然是我们的内存空间分配的问题,当我们malloc的数量,空间内存越来越大时,势必会造成堆内存的无限膨胀,。长期运行将会导致可用内存越来越少,程序也将会变得越来越卡顿。如果我们不手动释放,那就要到程序结束才会释放。可能会出现内存泄露(就是我们前边所提及到的)等问题
堆栈溢出/缓冲区溢出
使用过多的存储器时导致调用堆栈产生的溢出,也是缓冲区溢出中的一种
最常见的情况就是无限递归了
int fun()
{
//这里递归没有一个终止条件,会无限调用
return fun();
}
写在最后
- 关于递归,在之后的数据结构专栏我们还会涉及到(归并排序和快速排序等) , 还有不同语言的垃圾回收机制, 等到melo进一步学习了Java中的垃圾回收后,我们再来聊一聊!
"迷途"的野指针,都快找不着北了的更多相关文章
- 使用AFNetworking时, 控制器点击返回销毁了, 但还是会执行请求成功或失败的block, 导致野指针异常
原本我以为是我程序框架有问题...后来才知道, 无知真可怕... __unsafe_unretained __block typeof(self) weakSelf = self; AFHTTPSes ...
- 野指针与'关键字'NULL
野指针与'关键字'NULL 一.NULL是什么? 在C/C++中的标准定义: #ifdef __cplusplus //条件编译,判断是c++还是c环境 #define NULL 0 //c++环境 ...
- 关于空指针NULL、野指针、通用指针 (转)
reference:https://www.cnblogs.com/losesea/archive/2012/11/16/2772590.html 首先说一下什么是指针,只要明白了指针的含义,你就明白 ...
- 野指针(Wild pointer)和悬垂指针(dangling pointer)
详细参考如下: Dangling pointer(悬垂指针.迷途指针)和 Wild pointer(野指针) 迷途指针经常出现在混杂使用malloc() 和 free() 库调用: 当指针指向的内存释 ...
- 奇思妙想:利用野指针和lower_bound()/upper_bound()函数实现整数二分
众所周知,c++的STL中提供了三个二分查找函数,binary_search(),lower_bound(),upper_bound(),功能分别是找某值是否在数组中出现,找到数组中第一个大于等于某值 ...
- iOS开发_内存泄漏、内存溢出和野指针之间的区别
今天,在工作群中,被问到了内存泄漏和野指针指向的区别,自己答的不是很好,特意回来查了资料,在博文中总结一下经验,欢迎指正. 内存泄漏:是指在堆区,alloc 或new 创建了一个对象,但是并没有放到自 ...
- NULL指针、零指针、野指针
1.1.空指针 如果 p 是一个指针变量,则 p = 0; p = 0L; p = '\0'; p = 3 - 3; p = 0 * 17;p=(void*)0; 中的任何一种赋值操作之后, p 都成 ...
- 黑马程序员-nil Nil NULL NSNull 野指针和空指针
空指针1.空指针指不含有任何内存地址的指针.在没有具体初始化之前,其被符值为0Dog * dog = nil;Dog * dog = NULL;都为空指针2.野指针指指向的内存为垃圾内存,导致其值不确 ...
- C中的野指针—如何避免
转自:http://www.cnblogs.com/viviwind/archive/2012/08/14/2638810.html 先看一个例子: struct student{ char* nam ...
随机推荐
- GCN数据集Cora、Citeseer、Pubmed文件分析
简介 本文将对Cora.Citeseer.Pubmed 数据集进行详细介绍 Cora.Citeseer.Pubmed 数据集 来源 图 节点 边 特征 标签(y) Cora "Collect ...
- vm中安装win2012并安装hyper-V不支持嵌套
在虚拟机中安装win2012,并安装hyper-v提示: 无法安装hyper-v:虚拟机监控程序已经在运行 找到虚拟机目录下,用文本编辑器打开该系统的虚拟机配置文件(.vmx后缀),在配置文件末尾增加 ...
- Springboot实现VNC的反向代理
背景 用户需要通过前端HTML页面的noVNC(noVNC是什么?)客户端连接底层VNC Server服务端,为了防止VNC Server的IP暴露,因此需要做一层代理.正常情况下使用Nginx. ...
- Vite插件开发纪实:vite-plugin-monitor(下)
前言 上一篇介绍了Vite启动,HMR等时间的获取. 但各阶段详细的耗时信息,只能通过debug的日志获取 本文就实现一下debug日志的拦截 插件效果预览 --debug做了什么 项目启动指令 vi ...
- 这两个基础seo插件,wordpress网站必装
WordPress对搜索引擎非常友好,这一点很多人都知道.不过我们在制作完成WordPress主题后,还可以在原来的良好基础上,添加两个队seo非常有利的WordPress插件. 第一个插件:Baid ...
- Wireshark简单协议的抓包分析
一.实验目的 HTTP.TCP.UDP.ICMP.ARP.IP.FTP.TELNET查询分析 基本掌握查询命令的使用方法 二.实验环境 硬件环境:一台Windows7系统,一台XP系统 软件环境:VM ...
- 2020 年国内 Serverless 用户规模:阿里云占比第一,达 66%
在中国信息通信研究院重磅发布的国内首个<云原生用户调查报告>中,阿里云 Serverless 产品凭借在双十一的技术锤炼和丰富的应用实践,在国内 Serverless 用户规模的占比达到 ...
- 易华录 X ShardingSphere|葫芦 App 后台数据处理的逻辑捷径
"ShardingSphere 大大简化了分库分表的开发和维护工作,对于业务的快速上线起到了非常大的支撑作用,保守估计 ShardingSphere 至少为我们节省了 4 个月的研发成本.& ...
- Analysis Tools(分析工具)
分析工具 1.叠加分析 # Process: 交集取反 arcpy.SymDiff_analysis("", "", 输出要素类, "ALL" ...
- 前段之BOM ----DOM
一.介绍 BOM(Browser Object Model)是指浏览器对象模型,它使 JavaScript 有能力与浏览器进行"对话". DOM (Document Object ...