编写安全的代码的一些技巧

内存管理:

1.       坚持谁分配谁释放的原则, 某个类分配的内存应该由这个类来释放(主动或者被动的)。动态连接库分配的内存更应该如此。

2.       new/delete  new[]/delete[] malloc/free必须要严格配对。比如千万不要用free去释放由new分配的内存。

3.       不要把STL容器作为参数在动态库之间传来传去,因为你很难保证内存分配和释放的地方是一致的.

4.       不要把模板对象作为参数在动态库之间传来传去,因为你很也难保证内存分配和释放的地方是一致的. 甚至很难保证代码是一致的.

5.       delete一个对象的时候,要保证其它引用到这个对象的地方都知道这个对象被delete掉了. 因此最好的办法是学习COM的对象引用计数方法.

6.       函数永远不要返回局部对象的地址(包括引用), 因为函数结束的时候,这个地址虽然还有效.但是通常会被垃圾数据覆盖的.

7.       对于一个有虚拟函数的类,千万别用memset(this,….) 来清空自己, 因为这样在清空类的成员数据的时候也会把虚表给清空掉.

8.       如果一个类是虚类.那么它的析构函数也应该是虚的. 这样才会正确的调用到子类的析构函数, 不然容易发生内存泄漏.

9.       如果你的一个类是写在dll里的.而且准备输出的. 那么尽量把所有的函数都写到cpp里. 而且一定要把构造和析构函数都写到cpp里 . 哪怕他们一行代码都没有.免的内存分配释放的代码不一致.

10.    记得在适当的时候写拷贝构造函数和operator = 函数 , 因为如果你的类里分配了内存并用指针保存的时候, 不写这两个函数很容易造成内存被double free.

11.    复制一个字符串的时候,如果需要分配内存. 记住内存的大小是strlen() + 1, 千万记得那个1…..

12.    …. To be continue

 

防止Crash和方便Debug

1.            遵守内存管理节里的条款,能有效的减少程序的crash.

2.            使用一个指针前, 尽量的加判断, 防止非法指针的出现.

3.            指针变量一定要初始化. 不然容易造成条款2里的判断失效. 其它的变量也应该要记得初始化.

4.            删除一个对象的指针后, 应该把指针=NULL, 这是防止野指针的有效方法之一.

5.            注意检查下标的范围. 不管是数组的还是容器的.. 往大里说, 尽量要检查数据的合理性.不要对数据的合理性做任何假设. 对非法数据应该尽量予以纠正. 纠正失败后应该要记录log,并输出错误信息.以方便检查和调试.

6.            如上所说, 千万别吝啬log和assert.  Assert 往往能方便抓住那些异常的情况.  注意assert里不要写一些有意义的代码. 因为release版本情况下assert是被忽略的. 程序出现异常的时候 , 记得一定要记log, log到控制台,到文件.或者弹出对话框.最低限度,一定要下assert .

7.            注意检查函数的返回值, 配合条款6 , 能有效的防止很多能避免的crash..

8.            做容器的遍历的时候, 删除容器的某一项是要注意: (1)正确的删除, (2)删除后要记得容器大小是改变了的. (3)注意有可能连vector自己都会被释放掉的. 比如signal下连接了好多消息函数, 这个时候,应该把容器先复制一份. 再做循环.

9.            别在inline函数里声明静态变量….. 注意写在头文件里类的成员函数都是inline函数.

10.         在dll之间传递数据的时候,尽量使用标准C的数据类型和C++的纯虚接口(注意是没有成员变量的那种接口).

11.         C++类在做转化的时候, 从父类到子类转化的时候用dynamic_case<> . 而且注意判断转化的结果是不是NULL.

12.         …. To be continue

原文地址:https://www.cnblogs.com/kex1n/p/2286561.html