1、在代码审查时,检查函数体内的每一个“return”前是否有没有释放必须要释放的指针;
2、设计“struct”数据结构时,应当设计相应的释放“struct”指针的函数,并确保所有的“struct”体内的指针都被释放;
3、对于用动态内存建立的链表在释放时要一个一个结点去释放, 对于每一个链表也要有相应的链表内存管理函数,如链表的释放函数;
4、当一个指针变量要指向另一个动态内存地址时先检查一下该指针是否有指向另一个动态内存地址,如果有则应当考虑是否要先释放掉原先的指向的动态内存;
5、在调用一个函数时,对于函数的输出值要确认值的内存空间是否是在函数内部动态申请,如果是则应当考虑是适当的时候把它释放掉;
6、减少程序的出口的数目,最好是一个出口,在出口处理函数中确保释放所有的动态内存;
7、当用户强行退出时,要考虑在每一个退出点是否能够释放所有的动态内存;
8、释放掉一个指针所指的内存空间后,就立即把改指针置为空;
9、少用动态申请内存,能用数组代替的就用数组的形式;
10、尽量减少全局变量的使用,避免指针指向的混乱;
11、封装动态内存申请和释放的底层函数,便于检查内存泄漏问题;
12、把内存泄漏的检查方法放进设计代码中,便于发现内存泄漏。
程序运行异常预防措施
1、在释放指针前先检查指针是否为空;
2、当把指针作为参数传入C库函数中的参数时,先检查指针是否为空;
3、在函数体内,当要调用指针参数时,先判断该指针是否为空;
4、当要调用“struct”指针数据结构中的分体时要先判断该指针是否为空;
5、当做指针移动操作时要考虑指针是否会发生越界;
6、当一个函数体内可能会改变参数中的值时,要避免传入常量形式的值,在设计函数时要尽量避免试图去改变参数中的值;
7、动态申请完一个内存后要先检查是否申请成功;
8、对于一块连续的内存块和“struct”数据结构在第一次使用时要做初始化操作,如申请完内存后,记得用memset清空内存;
9、备案所有的全局变量,考虑全局变量对程序可能产生的影响,尽量少用全局变量。对于全局变量的定义最好使用“static”来申明,不让其它模块直接访问该全局变量,并且设计好相应的操作该全局变量的方法函数,在定义全局变量时要充分考虑好全局变量的初始化方法和程序结束时的处理方法,对于整个工程中的全局变量要进行登记管理,登记内容包括变量名、类型名、定义位置、使用范围、使用目的、初始化方法、程序结束时的处理方法及其它注意事项。
10、在用非ASCII(如中文字符、Unicode)编码时,要使用unsigned char*来申请空间,并记住申请空间大小,不要用C库中的字符串操作函数来操作。
11、记得申请足够的内存,比如,储存年份应该是5个空间而不是4个,记得保留‘\0’的空间;
12、在函数中最好不要定义占用内存太大的局部变量,否则容易造成栈溢出,对于较大内存的使用最好是使用堆内存空间的方法。由于栈溢出这种情况比较不常见,容易被人忽视,所以在发生因栈溢出而产生问题时往往不容易被发现原因所在;
13、尽量不频繁分配小块的内存;
14、在设计递归调用时要考虑递归调用可能的深度,防止出现栈溢出;
15、不要定义太多的局部变量,如果要定义一个数组类型的局部变量,数组不要太长,以防止出现栈溢出;
16、减少读写文件的次数,优化文件的读写方法。