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语言
    +关注

    关注

    180

    文章

    7533

    浏览量

    128812
  • 指针
    +关注

    关注

    1

    文章

    473

    浏览量

    70364

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

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

收藏 人收藏

    评论

    相关推荐

    C语言中链表的作用是什么?

    C语言中指针用的很少,链表、文件操作几乎没用过,所以也不能理解到底有什么作用。各位有经常在做程序时会用到这些吗。
    发表于 11-06 06:23

    C语言中数字怎么转成指针

    C语言中数字怎么转成指针,比如我要去内存地址为0x100的内容,用一句话表达,不如uchar a=?我要问号等于0x100地址的内容
    发表于 10-31 06:29

    C语言中ASCII代码是什么意思?

    C语言中ASCII代码是什么意思常见的ASCII代码都需要记吗
    发表于 10-25 07:10

    程序中出现了指针会导致什么后果?

    程序中出现了指针会导致什么后果
    发表于 10-12 07:43

    怎么避免程序中出现指针

    怎么避免程序中出现指针
    发表于 10-11 07:20

    C语言中的结构体指针在访问的时候怎么读取成员变量的数据?

    C语言中的结构体指针在访问的时候怎么读取成员变量的数据
    发表于 10-10 07:07

    c语言指针用法详解:如何使用指针变量做函数参数

    指针是C语言中一个比较重要的东西,有人说指针是C语言的灵魂这句话说的一点也没错。 正确灵活地运用它,可以有效地表达一些复杂的数据结构,比如系统的动态分配内存、消息机制、任务调度、灵活矩
    发表于 09-21 12:32 830次阅读
    c<b class='flag-5'>语言</b><b class='flag-5'>指针</b>用法详解:如何使用<b class='flag-5'>指针</b>变量做函数参数

    C语言中指针的基本概念和用法

    在C语言中指针是一项重要的概念,它允许我们直接访问和操作内存地址。
    发表于 08-17 15:30 517次阅读

    C语言中指针数组和数组指针的区别

    指针和数组之间存在着紧密的关系。在本文中,我们将探讨指针和数组的关系、指针算术和数组遍历、多维数组与指针以及指针数组和数组
    发表于 08-17 15:29 280次阅读

    C语言中指针和野指针的概念及产生原因

    在C语言中指针是一种非常强大和灵活的工具,但同时也容易引发一些问题,其中包括空指针和野指针
    发表于 08-16 16:18 402次阅读

    C语言中多级指针的概念和使用方法

    多级指针在C语言中是一种特殊的指针类型,它可以指向其他指针指针
    发表于 08-16 16:16 309次阅读

    C语言中指针函数和函数指针的概念及应用示例

    在C语言中指针函数和函数指针是强大且常用的工具。它们允许我们以更灵活的方式处理函数和数据,进而扩展程序的功能。
    发表于 08-16 16:14 344次阅读

    用图文和代码讲透C语言指针

    如果问C语言中最重要、威力最大的概念是什么,答案必将是指针!威力大,意味着使用方便、高效,同时也意味着语法复杂、容易出错。指针用的好,可以极大的提高代码执行效率、节约系统资源;如果用的不好,程序中将会充满陷阱、漏洞。
    发表于 06-08 09:42 157次阅读
    用图文和代码讲透C<b class='flag-5'>语言</b><b class='flag-5'>指针</b>

    C语言指针p、*p、&amp;p、*&amp;p、&amp;*p符号分别代表什么意思?

    在C语言中指针是非常重要的概念。指针是一个变量,其值为另一个变量的地址。使用指针可以直接访问内存中的数据,这使得C语言非常灵活和强大。
    的头像 发表于 05-29 15:05 2175次阅读

    C语言中一级指针、二级指针和三级指针

    一级指针的用法其实是取数据的地址,以此类推,二级指针就是取一级指针的地址,也可以表示一级指针的指向的内容。
    发表于 05-19 17:30 953次阅读
    C<b class='flag-5'>语言中</b>一级<b class='flag-5'>指针</b>、二级<b class='flag-5'>指针</b>和三级<b class='flag-5'>指针</b>