C/C++程序员有一半的工作量是花在处理由指针引起的bug

重磅干货,第一时间发货

C/C++中的指针给了程序员更多的灵活性,但它也是一把双刃剑。如果使用不当,会导致程序出现各种问题。有人说,C/C++程序员一半的工作量都花在了处理指针引起的bug上,可想而知指针所包含的坑有多么可怕。在这种情况下,我们在编写代码时应该小心。

如果想在写代码的时候尽量避免指针带来的问题,就需要知道指针使用不当会导致哪些问题,如何避免?下面总结一下使用指针时容易遇到的问题。

01. 避免内存泄漏

程序在运行时需要内存。同时,我们也知道内存是有限的,对于计算机来说是特别宝贵的资源。使用过的内存要及时归还给操作系统。

在c/c++中,如果是栈上的内存(比如函数中的局部非静态变量),使用后操作系统会自动为我们回收;但是如果是堆上动态分配的内存,我们需要手动释放。

如果我们忘记在程序中释放这些动态内存,而程序又是一个会继续运行的服务进程,那么内存使用率就会越来越高。

一句话,不再使用的内存不释放c语言动态申请内存,就叫内存泄露,内存泄露的问题很严重。好吧,我们来看几个内存泄漏的案例。

在 C/C++ 中,动态内存分配函数(如 malloc 系统函数)或 new 运算符分配的动态内存在使用后需要手动释放。否则会发生内存泄漏。

建议:写代码时注意malloc/free、new/delete成对

即使在 malloc/new 之后调用 free/delete 释放内存,释放内存的 free/delete 语句也有可能因为异常而无法执行,会发生内存泄漏。下面的例子就是这种情况。

从运行结果来看,类的析构函数并没有被执行,因此可以推断delete语句没有被执行。

有人会说,这不简单,直接在catch语句的cout

是的,这只是一个几十行代码的测试程序,你可能一下子就看出了问题c语言动态申请内存,但如果你面对一个巨大的项目,我想你的心一定是崩溃的。有一个更好的方法可以解决这个问题,那就是智能指针,稍后会专门介绍。

建议:多注意C++代码中智能指针的使用

02. 不要使用野指针

野指针,也称为悬空指针,是指向“垃圾”内存的指针。使用“野指针”会导致程序的行为不确定。

注意wild指针不是NULL指针,它比NULL指针更容易出错,因为不能通过if(NULL == p)形式的判断语句来防止,只能多注意写代码的时候。

指针p被释放或删除后,并没有设置为NULL,这让人误以为p是合法的指针。其实free或者delete只是释放指针指向的内存,但是指针的值依然是这块内存的地址。只是这块内存已经被回收,不能再被进程使用了​​。下面的例子是一个使用野指针的典型案例。

建议:free或delete后将对应指针设置为NULL

创建指针变量 p 时忘记初始化它。p 的值是一个随机的垃圾值。这时候读写指针是危险的,程序会有不确定的行为。

建议:尽量初始化指针变量,即使初始化为NULL

在c/c++中,局部变量存储在栈中,其特点是在函数调用时创建,函数结束时销毁。因此,在程序中返回局部变量的地址后,将其赋值给一个指针,该指针指向已经被回收的A内存,也是一个野指针。

看看下面的例子。本来想把fun函数中变量i的地址返回给p,用p访问这个变量。这打印出 *p 是 32767,而不是变量 i 的值。8.此类Bug一旦出现在大型项目中就很难定位。

建议:不要在函数中返回局部变量的地址。如果代码的逻辑不是局部变量的地址,那么局部变量必须声明为静态类型,因为静态变量的生命周期就是整个程序运行的持续时间。

03. 不要使用 NULL 指针

我们都知道程序中不能使用NULL指针,但是如果不注意,程序可能会意外使用NULL指针。让我们看两个容易出现问题的例子。

动态内存分配函数分配内存时,可能分配失败,此时返回NULL

从程序运行的结果来看,如果malloc分配NULL失败并赋值给p,然后访问p指向的0地址内存内容,就会出现“Segmentation fault”错误。

建议:使用内存分配函数分配内存时,应使用if(p==NULL)或if(p!=NULL)进行防错。

另外,在带有指针参数的函数中,也有可能误用了NULL指针。调用函数时,传递的指针是空指针。如果没有 if(p!=NULL) 判断条件,则稍后使用指针。当麻烦大的时候,下面的例子就是这样。

建议:对于带有指针参数的函数,还应该在函数入口处使用 if(p==NULL) 或 if(p!=NULL) 进行防错。

下载1:OpenCV-Contrib扩展模块中文版教程

下载2:Python视觉实战项目52讲

下载3:OpenCV实战项目20讲

交流群

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论