C++野指针和悬空指针的实现方法

作者:Linux猿 时间:2022-11-02 08:26:56 

目录
  • 一、野指针

  • 二、悬空指针

    • 2.1 情况一

    • 2.2 情况二

    • 2.3 情况三

野指针和悬空指针是指针中常见的两个概念,本文结合实例讲解来讲解下。

一、野指针

野指针是指尚未初始化的指针,既不指向合法的内存空间,也没有使用 NULL/nullptr 初始化指针。

来看一个简单例子:


#include <iostream>
using namespace std;

int main()
{
   int *p;     // 野指针
   int *q = NULL; // 非野指针
   p = new int(5);  // p 现在不再是野指针
   q = new int(10);
   cout<<"*p = "<<*p<<endl;
   cout<<"*q = "<<*q<<endl;
   free(p);
   free(q);
   return 0;
}

输出结果为:

linuxy@linuxy:~/wildPointer$ ./main
*p = 5
*q = 10
linuxy@linuxy:~/wildPointer$

p 在定义时并没有赋初值,这时候为野指针。

二、悬空指针

悬空指针是指 指针指向的内存空间已被释放或不再有效。

有三种情况会产生悬空指针,下面结合实例来看一下:

2.1 情况一

释放指针资源后,未再次赋值前。


#include <iostream>
using namespace std;

int main()
{
   int *p = new int(5);
   cout<<"*p = "<<*p<<endl;
   free(p);  // p 在释放后成为悬空指针
   p = NULL; // 非悬空指针
   return 0;
}

p 指针在被 free 后,成为悬空指针,被 NULL 赋值后不再是悬空指针。

注意:这里 free 掉的是 p 的内存空间,并不是变量 p,结合一个例子看下:


#include <iostream>
using namespace std;

int main()
{
   int *p = new int(5);
   cout<<"*p = "<<*p<<endl;
   cout<<"p 地址:"<<p<<endl;
   free(p);  // p 在释放后成为悬空指针
   cout<<"p 地址:"<<p<<endl;
   cout<<"*p = "<<*p<<endl;
   p = NULL; // 非悬空指针
   return 0;
}

输出结果为:

linuxy@linuxy:~/wildPointer$ ./main
*p = 5
p 地址:0x55a885ef6eb0
p 地址:0x55a885ef6eb0
*p = 0
linuxy@linuxy:~/wildPointer$

可以看到, free 前后 p 的地址是不变的,free 释放的是 p 指向的内存空间,释放后表示该快内存可以重新分配了,至于 free 后 *p 的值,视不同编译器情况而不同。

2.2 情况二

超出了变量的作用范围。


#include <iostream>
using namespace std;

int main()
{
   int *p;
   {
       int tmp = 10;
       p = &tmp;
   }
   //p 在此处成为悬空指针
   return 0;
}

在上述例了中,变量 tmp 的作用范围为最近的一层括号内,在括号外引用便超出了变量的作用范围。

2.3 情况三

指向了函数局部变量。


#include <iostream>
using namespace std;

int* getVal() {
   int tmp = 10;
   return &tmp;
}

int main()
{
   int *p = getVal(); //悬空指针
   cout<<"*p = "<<*p<<endl;
   return 0;
}

在函数 getVal 执行完后,局部变量的内存空间会被释放,而这里 p 指向了函数内的局部变量,p 便成为了悬空指针,可以将 tmp 变为 static 的。

来源:https://blog.csdn.net/nyist_zxp/article/details/119478944

标签:C++,野指针,悬空指针
0
投稿

猜你喜欢

  • springboot项目部署到宝塔的详细图文教程

    2023-03-27 05:24:31
  • Spring整合Junit的使用详解

    2022-11-20 18:33:17
  • SpringMVC实现文件上传与下载、拦截器、异常处理器等功能

    2023-07-21 19:18:44
  • Android RetainFragment状态保存的方法

    2023-06-03 03:35:08
  • Android studio 运行main 函数的方法

    2023-09-14 15:57:38
  • c#继承与多态使用示例

    2021-11-24 16:48:33
  • Springboot jar主清单属性丢失解决方案

    2022-04-06 05:30:26
  • C# wpf 通过HwndHost渲染视频的实现方法

    2023-08-30 03:33:35
  • Java SpringMVC数据响应超详细讲解

    2022-04-08 15:10:26
  • java返回集合为null还是空集合及空集合的三种写法小结

    2021-08-18 05:37:48
  • springboot自定义异常视图过程解析

    2023-06-29 09:44:36
  • Java JDBC连接数据库常见操作总结

    2021-12-01 23:01:40
  • springboot+jwt+springSecurity微信小程序授权登录问题

    2022-10-13 03:36:22
  • Android播放音乐案例分享

    2023-08-27 14:41:31
  • Android多媒体之VideoView视频播放器

    2023-11-12 14:38:35
  • c#打包文件解压缩的实例

    2022-07-22 11:20:20
  • Android编程单选项框RadioGroup综合应用示例

    2022-01-12 19:16:29
  • Spring cloud网关gateway进行websocket路由转发规则配置过程

    2022-01-24 01:48:38
  • C# log4net日志库的用法小结

    2023-12-26 18:50:44
  • SpringBoot接口中如何直接返回图片数据

    2023-04-22 13:10:24
  • asp之家 软件编程 m.aspxhome.com