悬垂指针
1、什么是悬垂指针
当所指向的对象被释放或者收回,但是对该指针没有作任何的修改,以至于该指针仍旧指向已经回收的内存地址,此情况下该指针便称悬垂指针(也叫迷途指针)。
2、悬垂指针的成因
在许多编程语言中(比如C),显示地从内存中删除一个对象或者返回时通过销毁栈帧,并不会改变相关的指针的值。该指针仍旧指向内存中相同的位置,即使引用已经被删除,现在可能已经挪作他用。
3、避免悬垂指针
1、智能指针。一个智能指针通常使用引用技术来收回对象。
2、tombstones 方法 和 locks-and-keys 方法
3、Boehm 垃圾收集器,一种保守的垃圾收集器,取代C和C++中的标准内存分配函数。此法通过禁止内存释放函数来完全消除悬垂指针引发的错误,通过收集垃圾来回收对象。
4、Sleep(n)睡眠后
vs2019 x86、vscode、Sublime Text
debug 版本:野指针指向的值等于睡眠时间 n或等于0
release版本:野指针乱指
#include <iostream>
#include <string>
#include <windows.h>
using namespace std;
int* ptr = NULL;
void fun() {
int i = 10;
ptr = &i;
}
int main(void) {
fun();
cout << "*ptr= " << *ptr << endl;
Sleep(100);
cout << "一秒钟后,fun()中的i变量的存储空间被释放, ptr所指对象的值为:" << endl << " *ptr = " << *ptr << endl;
printf("\n");
system("pause");
return 0;
}
野指针
1、什么是野指针
野指针的产生是由于在首次使用之前没有进行必要的初始化。因此,严格地说,在编程语言中的所有未初始化的指针都是野指针。
2、野指针的成因
- 指针变量没有被初始化
- 任何指针变量刚创建时不会自动称为NULL指针,它们的缺省值是随机的,乱指的。所以刚创建的指针变量应当被初始化,要么指针设置为NULL,要么让它指向合法的内存。
- 指针p被free或者delete之后,没有设置NULL
- 指针未置NULL,会让人误以为p是一个合法的指针。别看free和delete的名字(尤其是delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。通常会用语句if (p != NULL)进行防错处理。很遗憾,此时if语句起不到防错作用,因为即便p不是NULL指针,它也不指向合法的内存块。
- 指针操作超越了变量的作用范围
- 不要返回指向栈内存的指针或引用,因为栈内存在函数结束后就会被释放。
void free_str(void)
{
char* str = NULL;
str = (char*)malloc(100);
if (str != NULL) {
printf("%p\n", str);
}
free(str); //free只是释放了malloc所申请的内存,并不改变指针的值
//由于指针所指向的内存已经被释放,所以其它代码有机会改写其中的内容,相当于该指针从此指向了自己无法控制的地方,也称为野指针
//str = NULL; //为了避免失误,最好在free之后,将指针指向NULL
if (str != NULL) {
printf("%p\n", str);//当所指向的对象被释放或者收回,但是对该指针没有作任何的修改,以至于该指针仍旧指向已经回收的内存地址,此情况下该指针便称悬垂指针(也叫迷途指针)。
}
//野指针:严格地说,在编程语言中的所有为初始化的指针都是野指针。
}