0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C语言中的野指针是怎么来的?

Q4MP_gh_c472c21 来源:技术让梦想更伟大 作者:李肖遥 2021-06-01 16:43 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

一、什么是野指针?

指针是C语言的灵魂,同时也是很容易让人犯错的重难点,用错了指针将是一个灾难。

指针变量的本质是值,这个特殊的值是一个内存地址值,而合法的内存地址包括定义的变量的地址(栈)、malloc函数申请堆内存返回的地址(但未使用free释放,是在堆空间动态申请)

需要注意的是,野指针不是NULL指针,通常NULL指针可以使用if语句来判断,但是C语言中没有任何方法用来判断一个指针是否为野指针!

二、野指针是怎么来的?

通常野指针是因为指针变量中保存的值不是一个合法的内存地址或者指向不可用内存的指针而造成的。

而且野指针往往会造成内存越界、段错误等难以找到的问题,下面分几种情况来说说野指针的由来。

局部指针变量没有被初始化

//在win10_64位+vs2017

//来源:技术让梦想更伟大

//作者:李肖遥

#include 《stdio.h》#include 《string.h》

struct Student

{

char* name;

int number;

};

int main()

{

struct Student s;

strcpy(s.name, “Lixiaoyao”); // OOPS!

s.number = 99;

return 0;

}

局部变量不像全局变量那样,不赋值会自动初始化为0,指针name指向的内存空间地址是随机的,不能向随机地址空间写数据。我们在定义局部指针变量时应该初始化为NULL,局部变量则初始化为0

使用已经释放过后的指针

//在win10_64位+vs2017

//来源:技术让梦想更伟大

//作者:李肖遥

#include 《stdio.h》#include 《malloc.h》#include 《string.h》

void func(char* p)

{

printf(“%s

”, p);

free(p);

}

int main()

{

char* s = (char*)malloc(5);

strcpy(s, “Lixiaoyao”);//数组越界

func(s);

printf(“%s

”, s); // OOPS!使用已经释放的指针s

return 0;

}

malloc申请的堆空间释放后,意味着把这片内存归还到空闲链表,其它程序可以使用这片空间,如果其它程序使用了这个空间,可能导致其它程序莫名其妙的被关闭,所以一定要在释放过后将指针变量的值赋值为NULL。

指针所指向的变量在指针之前被销毁

//在win10_64位+vs2017

//来源:技术让梦想更伟大

//作者:李肖遥

#include 《stdio.h》

char* func()

{

char p[] = “Lixiaoyao”;

return p;

}

int main()

{

char* s = func();

printf(“%s

”, s); // OOPS!

return 0;

}

func函数被调用的时候,栈区存放了局部数组p,func返回之后,栈顶指针退出,占用的内存已经被释放掉,此时指针s指向一个被释放掉了栈空间,如果栈空间值被修改了,就不会打印出预期结果,s就变成了一个野指针,所以我们绝对不要在函数中返回局部变量和局部数组的地址。

进行了错误指针运算

//在win10_64位+vs2017

//来源:技术让梦想更伟大

//作者:李肖遥

#include 《stdio.h》

void main()

{

int a[10] = {1,2,3,4,5,6,7,8,9,10};

int *p;

for (int *p = &a[9];p 》= a;){

*--p = 0;

}

}

程序中在数组第1个元素a[0]被清除之后,指针p的值还继续减下去,而接下去的一次比较运算是用于结束循环的。但表达式p》= a(p 》= &a[0])的值是未定义的。

为避免这种情况,一定要确保字符数组要以‘’结尾,为防止内存越界,自己编写的内存相关函数需要指定正确的长度信息。

进行了错误的强制类型转换

//在win10_64位+vs2017

//来源:技术让梦想更伟大

//作者:李肖遥

#include 《stdio.h》#include 《string.h》

int main()

{

int a = 1;

int p = &a;

printf(“%d

”,*((int*)p));

/*

在64位下输出错误

32位下输出a的值 1

*/

return 0;

}

上面的程序在64位下输出错误,32位下输出a的值1,在我们写嵌入式程序的时候,会将int类型的一个数据强制转换成一个指针类型用来表示寄存器的地址,这个时候就需要注意了。

怎么避免野指针?

知道了野指针产生的原因,避免方法就出来了,在指针的解引用之前,确保指针指向一个绝对可用的空间。

定义指针时,同时初始化为NULL

在指针解引用之前,先去判断这个指针是不是Null

指针使用完之后,将其赋值为NULL

在指针使用之前,将其赋值绑定给一个可用地址空间

原文标题:详解C语言那些“可怕”的野指针

文章出处:【微信公众号:嵌入式ARM】欢迎添加关注!文章转载请注明出处。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    183

    文章

    7649

    浏览量

    146292
  • 指针
    +关注

    关注

    1

    文章

    484

    浏览量

    71998

原文标题:详解C语言那些“可怕”的野指针

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    指针与函数详解

    。 2、函数指针函数指针,本质上他是一个指针,并不是一个函数。在C语言中有些概念是一脉相承的,之前的推文《
    发表于 01-23 06:02

    C语言重点—指针

    C语言是比较偏底层的语言,为什么他比较偏底层,就是因为他的很多操作都是直接针对内存操作的。 这篇我们就来讲解C语言的一大特点,也是难点,
    发表于 01-22 08:23

    c语言中的代码优化

    。 第三招:数学方法解决问题   如今咱们演绎高效C语言编写的第二招--采用数学方法解决问题。数学是计算机之母,没有数学的依据和基础,就没有计算机的发展,因此在编写程序的时候,采用一些数学方**对程序
    发表于 01-12 09:45

    请教一个C语言指针问题,求解答

    C语言指针,多多少少还是有些难度的,容易有些混淆。 请教大家下面的这个表达式是啥意思呢? short (*p)[size] = (short (*)[size])0x8ff00000; 是否为在0x8ff00000地址处分
    发表于 01-12 08:14

    C语言指针p、*p、&p、*&p、&*p分别代表什么

    C语言中指针是非常重要的概念。指针是一个变量,其值为另一个变量的地址。使用指针可以直接访问内存中的数据,这使得
    发表于 01-07 07:34

    C语言回调函数原来这么简单

    ” 这个概念,它是回调函数能够实现的重要基础。 1、函数指针学习过C语言的伙伴都知道,C语言中的灵魂 —
    发表于 12-30 06:45

    请问C语言中整形溢出的解决方法有哪些?

    C语言中整形溢出的解决方法有哪些?
    发表于 12-29 07:33

    单片机c语言中定义字节怎么定义?

    定义位可以用***it但是定义字节呢?还有就是比如汇编中的DPTR的DPH和DPL在c语言中怎样定义的呢?
    发表于 12-29 06:32

    请问C语言中整形溢出会产生哪些异常行为?

    C语言中整形溢出会产生哪些异常行为?
    发表于 12-26 07:05

    请问C语言中整形溢出对哪些应用场景影响较大?

    C语言中整形溢出对哪些应用场景影响较大
    发表于 12-24 08:24

    Typedef在C语言中的应用

    Typedef 在C语言中频繁用以声明一个已经存在的数据类型的同义字。也可以用预处理器做类似的事。例如,思考一下下面的例子: #define dPS struct s * typedef
    发表于 12-22 13:53

    C语言中可以嵌套汇编语言吗?

    请问C语言中可以嵌套汇编语言吗?
    发表于 12-15 08:14

    C语言的分支结构介绍

    1.简单if语句 C语言中的分支结构语句中的if条件语句。 简单if语句的基本结构如下: 代码语言:javascript if(表达式) { 执行代码块; } 其语义是:如果表达式的值为真,则执行其后的语句,否则不执
    发表于 11-25 07:48

    C语言的常量介绍

    、-13; 实型常量:13.33、-24.4; 字符常量:‘a’、‘M’ 字符串常量:”I love china!” 在C语言中,可以用一个标识符表示一个常量,称之为符号常量。符号常量在使用之前必须先
    发表于 11-24 07:12

    Windows环境下32位汇编语言中文资料

    电子发烧友网站提供《Windows环境下32位汇编语言中文资料.rar》资料免费下载
    发表于 06-30 15:14 0次下载