找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 7720|回复: 35

C/C++指针使用常见的坑

  [复制链接]
  • 打卡等级:即来则安
  • 打卡总天数:28
  • 打卡月天数:7
  • 打卡总奖励:7961
  • 最近打卡:2025-12-22 17:16:30

3317

主题

285

回帖

2万

积分

管理员

积分
24106
发表于 2019-1-10 23:00:57 | 显示全部楼层 |阅读模式
C/C++中的指针让程序员有了更多的灵活性,但它同时也是一把双刃剑,如果用的不好,则会让你的程序出现各种各样的问题,有人说,C/C++程序员有一半的工作量是花在处理由指针引起的bug上,可想而知,指针中包含的陷阱是多么可怕。既然如此,我们在编写代码的时候就应该把好关。
要想在编写代码的时候尽可能避免指针带来的问题,就需要知道不恰当的使用指针到底会引发哪些问题, 又该如何去避免它?下面一起来总结在使用指针时容易遇到的问题。

避免内存泄露
程序在运行的时候需要内存,同时我们也知道内存是有限的,是计算机特别宝贵的资源,对于使用完的内存,应当及时的归还给操作系统
在c/c++中,如果是栈上的内存(比如说函数中的局部非静态变量),在使用完之后,操作系统会帮我们自动回收;但是如果是通过动态分配得到的堆上的内存,需要我们手动释放。
如果我们在程序中忘了释放这些动态内存,而程序又是会持续运行的服务进程,会导致内存占用越来越高,轻者致残影响系统性能,重者致命导致进程崩溃。
总之一句话,不再用到的内存没有释放,就叫做内存泄露,内存泄露的问题很严重。好了,让我们看几个内存泄露的案例。
在C/C++中,通过动态内存分配函数(如malloc系统函数)或者new运算符分配的动态内存在使用完之后需要手动释放。否则会造成内存泄露。
建议:代码编写时注意malloc/free, new/delete成对使用

即使在malloc/new后显示调用了free/delete释放内存,但是由于异常可能会导致释放内存的free/delete语句得不到执行,也会发生内存泄露,下面的例子就是这种情况。
从运行结果来看,类的析构函数没有被执行,可推知delete语句并没有得到执行。
有人会说,这还不简单,直接在catch语句的cout << "Something has gone wrong" << endl;下面之后加个delete t不就行了?
没错,这只是个几十行代码的测试程序,你可能一下就看出问题了,但是如果你面对的是一个庞大的工程时候,我想你内心一定是好崩溃的。还有更好的办法来解决这种问题,就是智能指针,后面会有专门的文章介绍。
建议:C++代码代码中多注意使用智能指针


不要使用野指针
野指针也叫悬挂指针,是指向“垃圾”内存的指针,使用“野指针”会让程序出现不确定的行为。
注意,野指针不是NULL指针, 它比NULL指针更容易犯错,因为它不能通过形如 if (NULL == p)的判断语句来预防,只能我们自己在写代码时多注意。
指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针,事实上free或delete只是把指针所指的内存给释放掉,但是指针的值还是这块内存的地址,只不过这块内存已经被回收了不能被该进程再使用,下面的例子就是一个典型的使用野指针的案例。
建议:free或delete之后将相应的指针设置为NULL


在创建指针变量p时忘了初始化,p的值是个随机的垃圾值,此时读写该指针都是危险的,程序会产生不确定的行为
建议:定义指针变量的时候尽量初始化,哪怕初始化为NULL也好  

c/c++中,局部变量是存放在栈中的,它的特点是随函数调用时创建随函数结束时销毁,因此在程序中将局部变量的地址返回后赋值给一个指针,这个指针指向的是一个已经被回收的内存,这也是一种野指针。
看看下面的例子,原本是想将fun函数中的变量i的地址返回给p,用p访问这个变量,这个打印出*p是32767,并不是变量i的值8。像这种bug,一旦在大的项目中出现是很难定位的。
建议:不要在函数中返回局部变量的地址,如果代码的逻辑非要是一个局部变量的地址,那么该局部变量一定要申明为static类型,因为static变量的生存期是整个程序运行期间


不要使用NULL指针
大家都知道,在程序中不能使用NULL指针,但是如果不注意,程序中还是有可能在你的意料之外就使用到NULL指针,下面看两个比较容易出问题的例子。
动态内存分配函数分配内存的时,有可能会分配失败,此时返回NULL
从程序运行结果来看,malloc分配失败返回NULL赋给p,再通过p访问其所指向的0地址内存内容时,出现"Segmentation fault"错误。
建议:在使用内存分配函数分配内存的时候,应该用i f(p==NULL) 或if(p!=NULL)进行防错处理。


此外,在含有指针参数的函数,也是有可能会误用到NULL指针,当调用该函数时传递的指针是个空指针,如果没有if(p!=NULL) 的判断条件,那么在后面使用指针的时候麻烦就大了,下面的例子就是这种情况。
建议:对于含有指针参数的函数,也应当在函数入口处用if(p==NULL) 或if(p!=NULL)进行防错处理。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
工控课堂 www.gkket.com

0

主题

175

回帖

390

积分

注册会员

积分
390
发表于 2019-1-10 23:10:20 | 显示全部楼层
看完楼主的帖子,我的心情竟是久久不能平息,受教了
工控课堂 www.gkket.com

0

主题

138

回帖

420

积分

注册会员

积分
420
发表于 2019-1-10 23:10:20 | 显示全部楼层
谢谢您的分享!
工控课堂 www.gkket.com

0

主题

165

回帖

319

积分

注册会员

积分
319
发表于 2019-1-10 23:45:37 | 显示全部楼层
我顶,我顶,我顶顶顶
工控课堂 www.gkket.com

0

主题

160

回帖

373

积分

注册会员

积分
373
发表于 2019-1-10 23:51:50 | 显示全部楼层
无私奉献,好工控人,32个赞送给你!!
工控课堂 www.gkket.com

0

主题

156

回帖

464

积分

注册会员

积分
464
发表于 2019-1-11 00:30:29 | 显示全部楼层
真是难得给力的帖子啊。
工控课堂 www.gkket.com

0

主题

142

回帖

392

积分

注册会员

积分
392
发表于 2019-1-11 00:58:40 | 显示全部楼层
楼主加油,我们都看好你哦。
工控课堂 www.gkket.com

0

主题

153

回帖

246

积分

注册会员

积分
246
发表于 2019-1-11 01:01:33 | 显示全部楼层
看到这帖子真是高兴!
工控课堂 www.gkket.com

0

主题

175

回帖

445

积分

注册会员

积分
445
发表于 2019-1-11 01:19:37 | 显示全部楼层
楼主您的技术水准,我最服你,其他都是浮云
工控课堂 www.gkket.com

0

主题

127

回帖

391

积分

注册会员

积分
391
发表于 2019-1-11 01:37:35 | 显示全部楼层
淡定,淡定,淡定……
工控课堂 www.gkket.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|手机版|免责声明|本站介绍|工控课堂 ( 沪ICP备20008691号-1 )

GMT+8, 2025-12-22 18:23 , Processed in 1.882441 second(s), 27 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表