C语言的空类型指针,空指针,野指针详解

 更新时间:2021年09月23日 15:12:19   作者:西红柿炒蛋不吃西红柿  
这篇文章主要介绍了C语言的空类型指针,空指针,野指针的详解及用法示例,介绍了其相关概念,然后分享了几种用法,具有一定参考价值。需要的朋友可以了解下。

空类型指针-void*

void是空类型,void*是空类型指针,又叫万能指针,就是该指针能接收任意类型的指针,可以指向任何类型对象,所以不能对空类型指针进行解引用,必须强制类型转换成相应的指针类型,才能进行解引用操作。

空指针类型:

  • 作为函数形参类型,可以接收任意类型的指针;
  • 作为函数返回值类型,在函数外面,将其强制类型转换为相应的指针类型
  • 可以与另一个void*类型指针比较大小

注意:空类型指针不能进行解引用操作;不能进行±整数运算。

空指针-NULL

在C语言中,空指针NULL指的是地址为0的那块空间

#define NULL((void*)0)

对于这块空间是不准我们进行访问的,所以,对NULL是不能进行解引用操作的,所以每次对指针进行解引用操作之前,我们要判断是否为空指针。

野指针

野指针是指向一个非法的或已销毁的内存的指针。

对野指针进行解引用操作是非法的。

造成野指针的原因

1.指针未初始化

int main()
{
	char* p;
	//此时p是野指针
	return 0;
}

没有对指针p进行初始化,此时p就是野指针,如果此时对p进行解引用操作,非法访问内存,程序就会崩溃。

2.指针越界访问

int main()
{
	int arr[] = {1,2,3,4,5};

	int* p = arr;

	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ",p[i]);
	}

	return 0;
}

虽然上面程序正常运行,但是其实越界访问了;只是仅仅访问了非法的内存空间,没有改变空间的值,程序有可能没来得及报错,但并不代表程序没有错,但是对于下面的代码,程序就会崩溃:

int main()
{
	int arr[10] = {0};
	int i = 0;
	int* p = arr;

	for (i = 0; i <= 10; i++)
	{
		*p = i;
		p++;
	}

	return 0;
}

因为这里非法访问内存的同时试图改变空间的值,所以程序崩溃。

3.指针指向的空间已经释放

char* fun()
{
	char arr[] = "abc";
	return arr;
}

int main()
{
	char* p = fun();
	printf("%s\n",p);
	return 0;
}

执行程序,给出如下警告

在这里插入图片描述

虽然程序没有崩溃,但是这种写法是非法的,arr是局部变量,函数调用结束,栈帧销毁,局部变量空间归还给操作系统,我们没有使用权限,此时p就是野指针,*p属于非法访问内存。

避免野指针

1.指针要进行初始化

指针要有初始值,初始化为NULL,或者有具体的指向。

既然NULL也不能进行解引用操作,那么为什么可以将指针初始化为NULL?这里初始化为NULL,只是为了给指针一个指向,但是实际使用时,我们并不能对NULL进行解引用操作,所以使用指针之前才要有效性判断。

2.使用指针之前要进行有效性判断

使用指针之前,要判断是否为NULL,如果为NULL,那么是不能进行解引用操作的

3.避免越界访问

不要进行越界访问操作,即使还是访问不改变值也是非法的

4.不要返回局部变量的地址

局部变量空间在函数到调用结束,就归还给操作系统,如果返回局部变量的地址,函数外面接收该返回值的指针就变成了野指针

5.当指针指向的空间释放后,要将该指针置为NULL

这样避免对野指针解引用操作,同时避免二次释放动态开辟的内存空间

int main()
{
	int* p = (int*)malloc(10*sizeof(int));
	
	//1.判断有效性
	if (p == NULL)
	{
		return -1;
	}
	
	//2.使用指针
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		p[i] = i;
	}
	
	//3.释放指针指向的空间
	free(p);

	//free(p);//非法操作
	//4.指针置为NULL
	p = NULL;

	free(p);//释放空指针什么都不做

	return 0;
}

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • 如何让C++函数返回值死心塌地为你工作

    如何让C++函数返回值死心塌地为你工作

    这篇文章主要介绍了如何让C++函数返回值死心塌地为你工作,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • C语言求素数的几种方式总结

    C语言求素数的几种方式总结

    这篇文章主要介绍了C语言求素数的几种方式总结,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • C语言八道笔试题精讲带你掌握指针

    C语言八道笔试题精讲带你掌握指针

    C语言这门课程在计算机的基础教学中一直占有比较重要的地位,然而要想突破C语言的学习,对指针的掌握是非常重要的,本文将具体针对指针的基础做详尽的介绍
    2022-07-07
  • 深入C++浮点数无效值定义与判定的解决办法

    深入C++浮点数无效值定义与判定的解决办法

    本篇文章是对C++中浮点数无效值定义与判定进行了介绍,需要的朋友参考下
    2013-05-05
  • QT中如何读写ini配置文件

    QT中如何读写ini配置文件

    ini文件在windows系统中可以存储需要持久保存的配置信息,QT界面中如何实现手动读取参数存放的位置,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • C语言实例实现二叉搜索树详解

    C语言实例实现二叉搜索树详解

    二叉搜索树是以一棵二叉树来组织的。每个节点是一个对象,包含的属性有left,right,p和key,其中,left指向该节点的左孩子,right指向该节点的右孩子,p指向该节点的父节点,key是它的值
    2022-05-05
  • 一文秒懂C语言/C++内存管理(推荐)

    一文秒懂C语言/C++内存管理(推荐)

    在C++中,内存分为:栈、堆、自由存储区、全局/静态存储区、常量存储区。这篇文章主要介绍了一文秒懂C语言/C++内存管理,需要的朋友可以参考下
    2020-11-11
  • C语言之strtol函数用法详解

    C语言之strtol函数用法详解

    这篇文章主要介绍了C语言之strtol函数用法详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C++11 模板参数的“右值引用”是转发引用吗

    C++11 模板参数的“右值引用”是转发引用吗

    这篇文章主要介绍了C++11 模板参数的“右值引用”是转发引用吗,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • C语言哈希表概念超详细讲解

    C语言哈希表概念超详细讲解

    哈希是一种很高效的存储数据的结构,它是利用的一种映射关系,它也是STL中unordered_map和unordered_set 的底层结构。本文,主要讲解哈希的原理,哈希的实现,里面关键点在于如何解决哈希冲突
    2023-02-02

最新评论