"迷途"的野指针,都快找不着北了
指针,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 ...
随机推荐
- python读取文件编码转换问题
encode(编码) decode(解码) encoding(编码格式) #-*- coding:utf-8 -*- import chardet #用于查看编码 with open(&quo ...
- 关于python中的可哈希与不可哈希
可哈希:简要的说可哈希的数据类型,即不可变的数据结构(字符串str.元组tuple.对象集objects).它是一个将大体量数据转化为很小数据的过程,甚至可以仅仅是一个数字,以便我们可以用在固定的时间 ...
- P3291-[SCOI2016]妖怪【凸壳】
正题 题目链接:https://www.luogu.com.cn/problem/P3291 题目大意 给出 \(n\) 个数字对 \((atk,dnf)\),求一个\((a,b)\). 对于每个数字 ...
- P7470-[NOI Online 2021 提高组]岛屿探险【Trie,CDQ分治】
正题 题目链接:https://www.luogu.com.cn/problem/P7470 题目大意 给出\(n\)个二元组\((a,b)\). \(q\)次询问给出\((l,r,c,d)\)表示询 ...
- 深入剖析 Spring WebFlux
一.WebFlux 简介 WebFlux 是 Spring Framework5.0 中引入的一种新的反应式Web框架.通过Reactor项目实现Reactive Streams规范,完全异步和非阻塞 ...
- CQOI2021 退役记
Day -1 晚上去了酒店然后就睡觉了. Day 1 进考场之前互相奶. 进了考场之后看题,发现T1很水(伏笔1,然后直接开始写 \(\Theta(n\log^2n)\)(二分+动态开点线段树),调了 ...
- 洛谷5038 [SCOI2012]奇怪的游戏(二分+网络流+判断奇偶)
寒假的时候就听过这个题.但是一直没有写. qwq 首先,我们发现题目中的图是个网格图,然后每次可以将相邻两个格子加一. 很容易就想到是黑白染色.那么每次操作,就相当于同时操作一个白点,一个黑点. 我们 ...
- 什么是Spring,SpringMVC,SpringBoot,SpringCloud?通俗易懂
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架.Spring使你能够编写更干净.更可管理.并且更易于测试的代码. Spring MVC是Spring的一个模块,一个web框 ...
- Hadoop MapReduce 保姆级吐血宝典,学习与面试必读此文!
Hadoop 涉及的知识点如下图所示,本文将逐一讲解: 本文档参考了关于 Hadoop 的官网及其他众多资料整理而成,为了整洁的排版及舒适的阅读,对于模糊不清晰的图片及黑白图片进行重新绘制成了高清彩图 ...
- 【UE4】GAMES101 图形学作业2:光栅化和深度缓存
总览 在上次作业中,虽然我们在屏幕上画出一个线框三角形,但这看起来并不是那么的有趣.所以这一次我们继续推进一步--在屏幕上画出一个实心三角形,换言之,栅格化一个三角形.上一次作业中,在视口变化之后,我 ...