野指针和悬空指针详解
野指针
野指针是指没有被初始化或指向未知、随机内存区域的指针。这种指针从未指向一个合法的内存地址,因此是完全不可预测的,可能指向任意地址。
出现情形
未初始化的指针:声明指针变量但未赋值,使其指向随机地址。
非法的指针运算:指针算术操作导致越界,指针指向无效区域。
int* p; //野指针 未初始化
int arr[5];
int* p1=arr+10;// 野指针 指向未知的内存
悬空指针
悬空指针是指向已被释放或超出作用域的内存区域的指针。此类指针原本指向有效的内存或对象,但当该内存被释放或对象生命周期结束后,指针依然指向这块无效的内存区域。
出现情形
指向内存被释放:指针被free或者delete后未及时置空
delete或者free是释放指针指向内存 指针本身并未被处理
int* p=new int(10);
cout<<p<<endl;
delete p;
cout<<p<<endl; /*delete后应该及时置空*/
可以看到虽然delete后指针对象仍然存在,但是指针已经失效,内存已被释放
指向已销毁的局部变量:函数内部的局部变量地址在函数返回后被销毁,指向它的指针就成为悬空指针
int* test()
{
int temp=10;
return &temp;
}
int*p =test(); //虽然返回了一个指针,但是这个指针已经失效因为 脱离作用域外对象销毁内存释放
#include <iostream>
using namespace std;
int main() {
int *p;
{
int a = 10;
p = &a; //a脱离作用域销毁内存释放
}
cout << p << endl; //p虽然有值但是指针已经失效
return 0;
}
悬空指针危害
1. 未定义行为
-
使用悬空指针访问或修改数据会导致未定义行为。因为指向的内存已经被释放,系统可能将该内存分配给其他对象或进程,导致不可预测的错误,包括数据篡改、程序崩溃等。
2. 程序崩溃
-
访问悬空指针可能导致程序试图访问无效的内存区域,从而触发操作系统的保护机制,导致程序崩溃。这种崩溃有时表现为段错误(Segmentation Fault)。
3. 数据损坏
-
如果悬空指针指向的内存被重新分配给其他变量或对象,程序可能无意中修改这些新的数据,导致数据污染或数据损坏。这类错误难以追踪和调试,因为它们可能表现为数据的异常变化,而并非立即崩溃。
4. 内存泄漏
-
当悬空指针存在时,程序员可能会误以为该指针仍然指向有效的内存,从而导致重复释放。重复释放一个已经被释放的内存块通常会导致未定义行为,甚至可能造成双重释放漏洞(Double Free Vulnerability)。
野指针和悬空指针编译器不会报错我们如何解决内存问题
点这里:C++内存泄漏检查工具——Valgrind