野指针概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)。

一、野指针成因

1、指针未初始化就使用

#include<stdio.h>
int main()
{int* p;                       *p = 10;  return 0;
}

此段代码中,局部变量p未初始化,也就意味着p为随机值没有方向,*p就会非法访问内存空间,此时p就为野指针。

有效改善方法:    初始化为空指针。如果定义指针的时候实在不知道赋什么值,可以先将其定义为空指针,即int*p=NULL;,NULL是代表空指针的意思,后面如果用到指针的话再让指针指向具有实际意义的地址,然后通过指针的解引用改变其指向的内容。

#include<stdio.h>
int main()
{int* p=NULL;int b = 8;p = &b;         *p = 100;printf("%d",*p);return 0;
}

2、指针越界访问

#include<stdio.h>
int main()
{int arr[10] = { 0 };int i = 0;int* p = arr;for (i = 0; i <= 10; i++){*p = i;                   //i=10时越界}return 0;
}

arr整型数组,有10个元素,初始化元素值为0,arr数组名表示首元素地址传给了指针p,通过对指针解引用改变数组元素值,当i=10时,此时*p访问的内存空间不在数组有效范围内,,此时*p就属于非法访问内存空间,p为野指针

3、指针指向空间的释放、

#include<stdio.h>
int* test()
{int a = 10;return &a;          //&a=0x0012ff40
}
int main()
{int* p = test();return 0;
}

程序开始后首先进入主函数,执行第一步,调用test函数将返回值赋给p,test函数的返回值是局部变量a的地址,假设a的地址为0x0012ff40,由于a只在test函数内有效,出了test函数其内存空间就被释放,也就意味着a的地址编号不存在,短时间内如果再次利用这块地址,它的值还未被改变也就是0x0012ff40还存在,p的值为0x0012ff40,但此时p为野指针,因为p里面所存放的地址是无效的。

二、 野指针的避免

1. 指针初始化
2. 小心指针越界
3. 指针指向空间释放即使置NULL
4. 避免返回局部变量的地址
5. 指针使用之前检查有效性

 

 三、关于内存空间释放的补充

代码:


#include<stdio.h>
int* test()
{int a = 10;return &a;
}
int main()
{int* p = test();printf("%d", *p);return 0;
}

 运行结果:

 分析:

由于a是test函数内的局部变量,而局部变量只有被调用时才会为其分配内存空间,所以进入主函数但未进入test函数时变量a没有内存空间,如上图所示

主函数的第一步首先调用test函数,进入test函数后执行到局部变量的定义时就会为其分配内存空间,如上图所示

​​​​​​​

通过对变量的赋值进而对内存空间赋予编号地址,如上图所示

test函数将局部变量a(int占4个字节)的地址返回给p,即p=0x005BF850,如上图所示

由于test函数运行完后test函数内的局部变量所占的内存空间会被释放,即a的内存空间编号0x005BF850不存在,但那块地址还是在的只不过不属于a了,如果没有其他函数调用这块地址,那块地址的名称暂时可能还是0x005BF850 ,观察图中内存窗口程序执行到p定义那一行时内存并未发生变化因为暂无其他函数使用这块空间,如上图所示

所以进行printf函数时打印p所指向的内容*p时还为10,但此时p为非法访问内存空间,为野指针。但如果在打印之前有其他函数调用了这块地址,这块地址的名称就会发生变化,不再是0x005BF850,打印p所指向的内容*p时不再为10。

观察图中内存窗口可以发现,执行完printf("%d", *p);后内存发生了变化

代码:

#include<stdio.h>
int* test()
{int a = 10;return &a;
}
int main()
{int* p = test();printf("Hello\n");printf("%d", *p);return 0;
}
#include<stdio.h>
int* test()
{int a = 10;return &a;
}
int main()
{int* p = test();printf("Hello\n");printf("Welcome!\n");printf("%d", *p);return 0;
}

 运行结果:

 分析:

由于进行printf函数打印p所指向的内容*p之前,Hello利用了那块儿内存,使得那块儿内存的名字不再是0x005BF850,变成了Hello地址的编号,所以打印p所指向的内容*p时的值不再是10,此时就为随机值了。

观察图中数据可以发现,程序执行完printf("Hello\n");时内存单元就发生了变化,是因此printf函数调用了内存,使得p的值发生了变化,*p也随着变化。

再执行完printf("Welcome!\n");时内存单元又发生了变化,是因此printf函数调用了内存使得p的值发生了变化,*p也随着变化。

执行完printf("%d", *p);时内存单元又发生了变化,是因此printf函数调用了内存使得p的值发生了变化,*p也随着变化。

初识C语言---野指针相关推荐

  1. C语言 野指针 - C语言零基础入门教程

    目录 一.简介 二.野指针产生的原因 1.指针变量未初始化 2.指针释放后之后未置空 三.避免野指针产生 1.初始化时置 NULL 2.释放时置 NULL 四.猜你喜欢 零基础 C/C++ 学习路线推 ...

  2. c语言野指针和空指针,C++中的空指针和野指针

    空指针常量 一个表示0值的整数常量,叫做空指针常量.例如:0.0L.1-1(它们都是值为0的整数常量表达式)以及(void*)0.void* NULL 都是空指针常量,空指针常量可以赋值给任何指针类型 ...

  3. c语言 指针_C语言野指针以及非法内存操作

    如果一个指针指向的内存没有访问权限,或者指向一块已经释放掉的内存,那么就无法对该指针进行操作,这样的指针称为野指针(Wild Pointer). 指向没有访问权限的内存 请看下面的代码: #inclu ...

  4. c语言野指针导致问题,C语言进阶之路(三)----野指针的产生原因及解决办法

    1.会产生野指针的做法 #include //这就是一种错误的写法 int main(){ int *p = NULL; p = (int *)malloc(); //释放P所指向的内存空间,但指针变 ...

  5. c语言野指针应用,C语言中野指针的深入解析

    C语言中野指针的深入解析 C语言中野指针这一块是C语言的难点,下面小编为大家带来了C语言中野指针的深入解析,欢迎大家阅读! "野指针"的成因主要有两种: (1)指针变量没有被初始化 ...

  6. c语言编程中野指针错误,小心C语言野指针

    指针是C语言一个很强大的功能.然而所谓成也萧何,败也萧何,用好了指针会使程序大放异彩,用错了指针轻者只是报个错,重者可能整个系统都崩溃了.本篇我们来谈谈指针一种错误的使用方法"野指针&quo ...

  7. C语言野指针产生的情况

    在大型项目中我们对指针的应用是需要非常谨慎的,一不留神可能就会产生野指针或者造成内存泄漏. 以下情况是产生野指针的几种原因和实例. 一:指针为初始化直接使用 #include <stdio.h& ...

  8. c语言编程中野指针错误,C语言(野指针错误)

    realloc引起的coredump 记录一次接口程序在运行过程中产生的崩溃问题,通过调试 core文件,定位到是程序在调用realloc 时候出现了问题 问题程序代码 #include #inclu ...

  9. 关于C语言野指针的问题

    typedef struct {         int id;         char username [6]; } user; int main(void) {         user *u ...

最新文章

  1. 前辈说先学会了这些Python知识点,再谈学习人工智能、机器学习
  2. 学习换脸:Switching Eds: Face swapping with Python, dlib, and OpenCV
  3. 购物车清除的php,php-如何清除废弃的woocommerce购物车
  4. vue指令:v-cloak渲染指令(v-cloak 指令是解决屏幕闪动的好方法)
  5. AIX-vi操作-提示Unknown terminal type的问题解决方法
  6. php中update()函数,update_option()函数
  7. Java并发之Condition的实现分析
  8. 【BZOJ2281】【博弈论+DP】 [Sdoi2011]黑白棋
  9. JavaWeb书城项目(尚硅谷视频整理自用)
  10. 路由器登陆密码破解方法
  11. 微信小程序全国巡回沙龙杭州站-芋头演讲详细内容及PPT
  12. Illegal base64 character 20
  13. 单片机继电器控制实验程序C语言,用单片机通过继电器来控制电热水器的实验...
  14. H.266/VVC代码学习:MIP技术相关代码之initIntraMip函数
  15. python 布莱克舒尔斯_布莱克—舒尔斯期权定价模型
  16. LMS、kalman、RLS的Matlab仿真
  17. 可惜知乎没有注销账号的选项
  18. 搭建asp会议签到系统 第四章 会议统计
  19. 了解数据的发展历程--大数据简史
  20. 关于SM总线控制器驱动的安装

热门文章

  1. java中415是什么异常_@RequestBody 错误415问题如何解决
  2. C/C++开发,物联网通信-如何基于TCP/IP简要设计业务应用协议(c++案例)
  3. 全网首次解密600多个AI工具汇总(三)
  4. GEE入门之路(从【初学者】角度,大白话)——附海面风速插值代码
  5. Android AssetManager初探
  6. 283-Go语言的变量
  7. UVALive 6848 Fishing(dp)
  8. 半路出家,就是那种只看一些经文的和尚
  9. 蓝桥杯—三羊献瑞,祥瑞生辉+三羊献瑞
  10. 使用JAVA实现对游戏《植物大战僵尸》游戏数据进行修改