一、缓冲区溢出,使用不安全的函数
例如strcpy、sprintf、strcat、scanf等
应换用更安全的函数或者判断传入参数的大小,防止超过缓冲区大小。
strcpy()可改用strncpy(),并在最后添加0结尾符;sprintf()可改用snprintf();strcat()可改用strncat();scanf()可改用scanf_s()
二、处理问题时出错
- 未检查返回值的情况下调用函数
- 将负值用作了期望正值的函数的参数.
三、错误的表达式
- 可能除零
- .错误的sizeof()
-
S2IDString tIDString; memset(&tIDString,0,sizeof(SIDString));
-
- 复制错误。
Jint32 baseDirIndex = baseDirStr.find('/'); if(baseDirIndex!=-1) { baseDirStr = baseDirStr.mid(baseDirStr.find('/')+1); } else { baseDirStr = QString::null; } Jint32 currentIndex = currentDirStr.find('/'); if(currentIndex!=-1) { currentDirStr = currentDirStr.mid(currentDirStr.find('/')+1); } else { baseDirStr = QString::null; }
- 条件是多余的,无论结果如何,执行的代码相同
-
if(pTermStruct == G_NULL) { return 1; } return 1 ;
-
四、控制流问题
无法到达的语句:不带符号的值判断>0,值永远为true
五、内存泄漏
- 非法访问
strlen:将不以 null 终止的字符缓冲区传递给了期望获得以 null 终止的字符串的函数
strncpy:大小应减1,并结尾加0
- 内存泄漏
针对标量或使用 new[] 分配的指针数组使用了非数组删除
六、初始化
- 非void函数需要有返回值
- 变量使用前未初始化
- 标量字段未被构造函数初始化
非静态类成员,在此构造函数或其调用的任何函数中未初始化
七、API使用错误
- 使用 va_start 或 va_copy 来开始处理;未使用 va_end 来结束
- 参数过多或过少,例如:未使用,但却传入了参数。
-
sprintf(tmpBuf, "YVal", ProcTime.GetMonth()); sql.Format("SELECT %s, %s FROM ",sHours[0]);
-
- 格式转换不兼容,例如%d,期望"int",但传入参数为"unsigned long";%s期望"char *",但传入"QString"
- 源缓冲区可能与目标缓冲区重叠,这会导致 "memcpy" 的未定义行为
-
memcpy(chPos, chPos+2, sizeof(char)*(strlen(i_pData->szBJName) - nPos-2)); memset(chPos+strlen(chPos)-2, 0, sizeof(char)*2);
-
八、明文存储密码