"迷途"的野指针,都快找不着北了
指针,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 ...
随机推荐
- Jmeter系列(35)- 设置JVM内存
场景 单台机器的下JMeter启动较大线程数时可能会出现运行报错的情况,或者在运行一段时间后,JMeter每秒生成的请求数会逐步下降,直到为0,即JMeter运行变得很"卡",这时 ...
- Shell系列(23)- 字符截取命令sed
简述 字符替换命令sed 和vi功能相似,但是vi是给用户用的,sed是给脚本用的 sed是一种几乎包括在所有的UNIX平台(包括Linux)的轻量级流编辑器.s sed主要是用来将数据进行选取.替换 ...
- Java 知识点 列表
* Java SE Java开发基础 Java异常处理 Java泛型与反射 Java IO基础 JUnit单元测试 Java多线程开发 Maven基础 https://www.yiibai.com/ ...
- find_elements与find_element的区别
find_element不能使用len,find_elements可以使用len获取元素数量,判断页面有无某个元素,这个方法可以用来断言. 如添加用户后,判断是否添加成功. 删除用户后,判断是否删除成 ...
- P4180-[BJWC2010]严格次小生成树【Kruskal,倍增】
正题 题目链接:https://www.luogu.com.cn/problem/P4180 题目大意 \(n\)个点\(m\)条边的一张无向图,求它的严格次小生成树. \(1\leq n\leq 1 ...
- Sentry 监控 - Alerts 告警
系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...
- SVN服务器的环境搭建(图文并茂)
SVN服务器的搭建与使用 本章读完,就可以创建代码版本库,传送门 https://www.cnblogs.com/zzpython/p/13348009.html TortoiseSVN 是 Subv ...
- 【C++ Primer Plus】编程练习答案——第7章
1 double ch7_1_harmonicaverage(double a, double b) { 2 return 2 / (1 / a + 1 / b); 3 } 4 5 void ch7_ ...
- docker之swarm容器部署及运维
1.概念 Docker Swarm 是 Docker 的集群管理工具.它将 Docker 主机池转变为单个虚拟 Docker 主机. Docker Swarm 提供了标准的 Docker API,所有 ...
- Elasticsearch 存储成本省 60%,稿定科技干货分享
背景 稿定科技旗下稿定设计产品是一个聚焦商业设计的多场景在线设计平台,打破了软硬件间的技术限制,汇集创意内容与设计工具于一体,为不同场景下的设计需求提供优质的解决方案,满足图片.视频等全类型媒介的设计 ...