一.访问越界问题之越界保护(out_of_range异常):
1.数组和顺序容器越界:array,string,vector的下标操作[], ->at()操作都会产生out_of_range,须做越界保护。
1.1 string string.substr(size_t pos, size_t len),当pos=string.lengh()的时候,会返回一个空字符串,>leghth的时候会产生out_of_range.
1.2string.find_first_of(char*,size_t pos),不会产生异常,只会返回string::npos,就是-1
1.3map[]的下标操作是当pair不存在就insert pair,map->at()会抛出异常,应该find() != map.end();
二.运算符和优先级以及变量类型容易引发的错误:
2.1bool值的判断:指针void* p, if(!p) 等价 p == NULL;返回值为int型最好不要用!(ret)来判断,容易引发错误。如:
FILE* fp = fopen(), fclose(fp) == 0,为关闭成功。而!feof()是因为其返回的是bool值, getc() == EOF来判断文件结尾。
2.2运算符优先级。千万不要!!while(size_t pos = find != io_base::npos)这种骚操作,具体原因自己想。
2.3struct{ string str}:这种C98编译器会编译通过,但是是core dump,C11才能正常运行,所以最好放弃这种东西。
2.4goto tail:的使用, fopen(),goto tail: fclose(),这样不会因为return 跳过。
2.5#define ((x), (y)) ((x) + (y)):最好用括号包起来,才是最安全的做法。
三.程序控制流造成的错误:
3.1return回跳过 fopen(),fclose(), new(),delete(), DIR* dir = opendir(), closedir(dir)这些操作所以最好用
goto tail: delete 资源。资源不能重复释放,最好 !dir; closedir(dir); dir = NULL;代码干净,不留尾巴
3.2函数调用 vector().clear(), -> vector.insert(),这样重复调用借口才不会发生逻辑错误。
四.局部变量(自动变量)的生存周期:
4.1不能返回局部变量的指针和引用,++i为对象的引用,i++为值 printf(++i, i++),函数形参从右至左(编译器决定,所以这种代码要避免)
4.2goto tail会跳过一些变量的定义
4.3 static 全局变量不能被其他头文件使用,不能被extern,作用域为当前头文件,const 全局变量需要extern才能可见
4.4局部变量定义未初始化行为是不可定义的,数组要memset()
2. a/b :先判断b不等于0
3.int a = 0 :定义就初始化,防止没有赋值就使用,自动变量
4.map insert当数据存在时,不会做操作
5.vs dll和exe所在堆不同,共享内存要注意
6.class static 成员:类的静态成员必须定义类的时候就必须初始化static成员,否则会编译不过。(VS现在类static成员必须在cpp中定义,放在h中定义编译会报错)
7.createThrad对应单线程CRT。 _beginThreadEx对应多线程CRT。