首页 > 系统相关 >cpp内存泄漏和代码检查工具

cpp内存泄漏和代码检查工具

时间:2024-04-03 17:23:12浏览次数:13  
标签:function 泄漏 usage variable 内存 cpp using pointer condition

cppcheck

cppcheck属于静态代码检查工具,能处理以下类型:

  • 64-bit portability:
    Check if there is 64-bit portability issues:

    • assign address to/from int/long
    • casting address from/to integer when returning from function
  • Assert:
    Warn if there are side effects in assert statements (since this cause different behaviour in debug/release builds).

  • Auto Variables:
    A pointer to a variable is only valid as long as the variable is in scope.
    Check:

    • returning a pointer to auto or temporary variable
    • assigning address of an variable to an effective parameter of a function
    • returning reference to local/temporary variable
    • returning address of function parameter
    • suspicious assignment of pointer argument
    • useless assignment of function argument
  • Boolean:
    Boolean type checks

    • using increment on boolean
    • comparison of a boolean expression with an integer other than 0 or 1
    • comparison of a function returning boolean value using relational operator
    • comparison of a boolean value with boolean value using relational operator
    • using bool in bitwise expression
    • pointer addition in condition (either dereference is forgot or pointer overflow is required to make the condition false)
    • Assigning bool value to pointer or float
    • Returning an integer other than 0 or 1 from a function with boolean return value
  • Boost usage:
    Check for invalid usage of Boost:

    • container modification during BOOST_FOREACH
  • Bounds checking:
    Out of bounds checking:

    • Array index out of bounds
    • Pointer arithmetic overflow
    • Buffer overflow
    • Dangerous usage of strncat()
    • Using array index before checking it
    • Partial string write that leads to buffer that is not zero terminated.
    • Check for large enough arrays being passed to functions
  • Check function usage:
    Check function usage:

    • missing 'return' in non-void function
    • return value of certain functions not used
    • invalid input values for functions
    • Warn if a function is called whose usage is discouraged
    • memset() third argument is zero
    • memset() with a value out of range as the 2nd parameter
    • memset() with a float as the 2nd parameter
    • copy elision optimization for returning value affected by std::move
  • Class:
    Check the code for each class.

    • Missing constructors and copy constructors
    • Constructors which should be explicit
    • Are all variables initialized by the constructors?
    • Are all variables assigned by 'operator='?
    • Warn if memset, memcpy etc are used on a class
    • Warn if memory for classes is allocated with malloc()
    • If it's a base class, check that the destructor is virtual
    • Are there unused private functions?
    • 'operator=' should check for assignment to self
    • Constness for member functions
    • Order of initializations
    • Suggest usage of initialization list
    • Initialization of a member with itself
    • Suspicious subtraction from 'this'
    • Call of pure virtual function in constructor/destructor
    • Duplicated inherited data members
    • Check that arbitrary usage of public interface does not result in division by zero
    • Delete "self pointer" and then access 'this'
    • Check that the 'override' keyword is used when overriding virtual functions
    • Check that the 'one definition rule' is not violated
  • Condition:
    Match conditions with assignments and other conditions:

    • Mismatching assignment and comparison => comparison is always true/false
    • Mismatching lhs and rhs in comparison => comparison is always true/false
    • Detect usage of | where & should be used
    • Duplicate condition and assignment
    • Detect matching 'if' and 'else if' conditions
    • Mismatching bitand (a &= 0xf0; a &= 1; => a = 0)
    • Opposite inner condition is always false
    • Identical condition after early exit is always false
    • Condition that is always true/false
    • Mutual exclusion over || always evaluating to true
    • Comparisons of modulo results that are always true/false.
    • Known variable values => condition is always true/false
    • Invalid test for overflow. Some mainstream compilers remove such overflow tests when optimising code.
    • Suspicious assignment of container/iterator in condition => condition is always true.
  • Exception Safety:
    Checking exception safety

    • Throwing exceptions in destructors
    • Throwing exception during invalid state
    • Throwing a copy of a caught exception instead of rethrowing the original exception
    • Exception caught by value instead of by reference
    • Throwing exception in noexcept, nothrow(), attribute((nothrow)) or __declspec(nothrow) function
    • Unhandled exception specification when calling function foo()
    • Rethrow without currently handled exception
  • IO using format string:
    Check format string input/output operations.

    • Bad usage of the function 'sprintf' (overlapping data)
    • Missing or wrong width specifiers in 'scanf' format string
    • Use a file that has been closed
    • File input/output without positioning results in undefined behaviour
    • Read to a file that has only been opened for writing (or vice versa)
    • Repositioning operation on a file opened in append mode
    • The same file can't be open for read and write at the same time on different streams
    • Using fflush() on an input stream
    • Invalid usage of output stream. For example: 'std::cout << std::cout;'
    • Wrong number of arguments given to 'printf' or 'scanf;'
  • Leaks (auto variables):
    Detect when a auto variable is allocated but not deallocated or deallocated twice.

  • Memory leaks (address not taken):
    Not taking the address to allocated memory

  • Memory leaks (class variables):
    If the constructor allocate memory then the destructor must deallocate it.

  • Memory leaks (function variables):
    Is there any allocated memory when a function goes out of scope

  • Memory leaks (struct members):
    Don't forget to deallocate struct members

  • Null pointer:
    Null pointers

    • null pointer dereferencing
    • undefined null pointer arithmetic
  • Other:
    Other checks

    • division with zero
    • scoped object destroyed immediately after construction
    • assignment in an assert statement
    • free() or delete of an invalid memory location
    • bitwise operation with negative right operand
    • provide wrong dimensioned array to pipe() system command (--std=posix)
    • cast the return values of getc(),fgetc() and getchar() to character and compare it to EOF
    • race condition with non-interlocked access after InterlockedDecrement() call
    • expression 'x = x++;' depends on order of evaluation of side effects
    • overlapping write of union
    • either division by zero or useless condition
    • access of moved or forwarded variable.
    • redundant data copying for const variable
    • subsequent assignment or copying to a variable or buffer
    • passing parameter by value
    • Passing NULL pointer to function with variable number of arguments leads to UB.
    • C-style pointer cast in C++ code
    • casting between incompatible pointer types
    • Incomplete statement
    • check how signed char variables are used
    • variable scope can be limited
    • unusual pointer arithmetic. For example: "abc" + 'd'
    • redundant assignment, increment, or bitwise operation in a switch statement
    • redundant strcpy in a switch statement
    • Suspicious case labels in switch()
    • assignment of a variable to itself
    • Comparison of values leading always to true or false
    • Clarify calculation with parentheses
    • suspicious comparison of '\0' with a char* variable
    • duplicate break statement
    • unreachable code
    • testing if unsigned variable is negative/positive
    • Suspicious use of ; at the end of 'if/for/while' statement.
    • Array filled incompletely using memset/memcpy/memmove.
    • NaN (not a number) value used in arithmetic expression.
    • comma in return statement (the comma can easily be misread as a semicolon).
    • prefer erfc, expm1 or log1p to avoid loss of precision.
    • identical code in both branches of if/else or ternary operator.
    • redundant pointer operation on pointer like &*some_ptr.
    • find unused 'goto' labels.
    • function declaration and definition argument names different.
    • function declaration and definition argument order different.
    • shadow variable.
    • variable can be declared const.
    • calculating modulo of one.
    • known function argument, suspicious calculation.
  • STL usage:
    Check for invalid usage of STL:

    • out of bounds errors
    • misuse of iterators when iterating through a container
    • mismatching containers in calls
    • same iterators in calls
    • dereferencing an erased iterator
    • for vectors: using iterator/pointer after push_back has been used
    • optimisation: use empty() instead of size() to guarantee fast code
    • suspicious condition when using find
    • unnecessary searching in associative containers
    • redundant condition
    • common mistakes when using string::c_str()
    • useless calls of string and STL functions
    • dereferencing an invalid iterator
    • reading from empty STL container
    • iterating over an empty STL container
    • consider using an STL algorithm instead of raw loop
    • incorrect locking with mutex
  • Sizeof:
    sizeof() usage checks

    • sizeof for array given as function argument
    • sizeof for numeric given as function argument
    • using sizeof(pointer) instead of the size of pointed data
    • look for 'sizeof sizeof ..'
    • look for calculations inside sizeof()
    • look for function calls inside sizeof()
    • look for suspicious calculations with sizeof()
    • using 'sizeof(void)' which is undefined
  • String:
    Detect misusage of C-style strings:

    • overlapping buffers passed to sprintf as source and destination
    • incorrect length arguments for 'substr' and 'strncmp'
    • suspicious condition (runtime comparison of string literals)
    • suspicious condition (string/char literals as boolean)
    • suspicious comparison of a string literal with a char* variable
    • suspicious comparison of '\0' with a char* variable
    • overlapping strcmp() expression
  • Type:
    Type checks

    • bitwise shift by too many bits (only enabled when --platform is used)
    • signed integer overflow (only enabled when --platform is used)
    • dangerous sign conversion, when signed value can be negative
    • possible loss of information when assigning int result to long variable
    • possible loss of information when returning int result as long return value
    • float conversion overflow
  • Uninitialized variables:
    Uninitialized variables

    • using uninitialized local variables
    • using allocated data before it has been initialized
  • Unused functions:
    Check for functions that are never called

  • UnusedVar:
    UnusedVar checks

    • unused variable
    • allocated but unused variable
    • unread variable
    • unassigned variable
    • unused struct member
  • Using postfix operators:
    Warn if using postfix operators ++ or -- rather than prefix operator

  • Vaarg:
    Check for misusage of variable argument lists:

    • Wrong parameter passed to va_start()
    • Reference passed to va_start()
    • Missing va_end()
    • Using va_list before it is opened
    • Subsequent calls to va_start/va_copy()

如何使用

# 分析目录
cppcheck <path to dir>

# 分析单个文件
cppcheck <path to cpp file>

valgrind

valgrind 是一个动态分析工具,包含memcheckcachegrind,massif等模块,可以用来检查内存使用,堆栈分析,CPU缓存操作等。

如何使用

# 使用memcheck工具,需保证<program>带有符号信息,即`-g`编译
valgrind <program>

对下面这段程序进行测试

int main() {
  int *i = new int(9);
  std::cout << *i << std::endl;

  // delete i;
}

测试结果如图所示,这种级别的内存泄漏都能检查出来:

img

Sanitizer

Sanitizers是Google发起的开源工具集,包括AddressSanitizer, MemorySanitizer, ThreadSanitizer, LeakSanitizer
Sanitizers 项目本是LLVM项目的一部分,但GNU也将该系列工具加入到了自家的GCC编译器中。

如何使用

Sanitizer 用法示例 说明
AddressSanitizer gcc -fsanitize=address -g -o program program.c 检测内存错误,如使用未初始化的内存、内存泄漏、缓冲区溢出等。
ThreadSanitizer gcc -fsanitize=thread -g -o program program.c 检测多线程程序中的数据竞争问题。
MemorySanitizer gcc -fsanitize=memory -g -o program program.c 检测未初始化的内存访问。
UndefinedBehaviorSanitizer (UBSan) gcc -fsanitize=undefined -g -o program program.c 检测C/C++程序中的未定义行为。例如,整数溢出、空指针引用等。
LeakSanitizer (实验性) gcc -fsanitize=leak -g -o program program.c 检测内存泄漏。

搭配CMake时,使用方式如下:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")

同样对上面的cpp代码片段进行测试,效果如下:
img

标签:function,泄漏,usage,variable,内存,cpp,using,pointer,condition
From: https://www.cnblogs.com/ericling0529/p/18113147

相关文章

  • 如何查看KingbaseES数据库占用操作系统内存情况
    当遇到数据库内存告警,并且操作系统内存使用不足,需要分析内存占用的方法。KingbaseES数据库使用操作系统缓存机制,大量的内存很可能被BUFFER/CACHE占用了。从free命令可以看到总共有2.5G多内存,使用了291MB,free剩下1.7GB多,BUFF/CACHE占了474MB。available有1.3GB多,当前这台数据库服......
  • OpenMLDB vs Redis 内存占用量测试报告
    1.背景OpenMLDB是一款开源的高性能全内存SQL数据库,在时序数据存储、实时特征计算等方面都有很多创新和优化。Redis是业界最流行的内存存储数据库,广泛应用于缓存等高性能在线场景。虽然二者应用场景不尽相同,但作为都是使用内存作为存储介质的数据库,希望通过对相同数据行数下......
  • C++内存管理
    内存管理1、C/C++内存分布2、C++动态内存管理方式2.1new和delete2.2operatornew与operatordelete函数2.3定位new3、附录3.1malloc/free和new/delete的区别1、C/C++内存分布intglobalVar=1;staticintstaticGlobalVar=1;voidTest(){staticints......
  • 整型之韵,数之舞:大小端与浮点数的内存之旅
    ✨✨欢迎......
  • 内存爆满的一些解决处理(简)
    ###服务器内存爆满的解决办法>由于我们购买的服务器或者挂机宝在一些情况下,配置很低。基本上都是1核1G的,1G的内存对于想要部署多个服务的我们肯定不够用,解决内存爆红十分有必要,下面是我的一些整理核总结,关于如何缓解内存问题####1.虚拟内存在大多数情况下,我们的内存很小......
  • 手写简易操作系统(二十)--实现堆内存管理
    前情提要前面我们实现了0x80中断,并实现了两个中断调用,getpid和write,其中write还由于没有实现文件系统,是个残血版,这一节我们实现堆内存管理。一、arena在计算机科学中,“arena”内存管理通常指的是一种内存分配和管理技术,它通常用于动态内存分配和释放。在这种管理......
  • Tomcat内存马分析
    前言自己简单搭建一个Tomcat项目,IDEA里选择JavaEE,勾上web就行了加个依赖(这样就能找到三个Context了:<dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-core</artifactId><version>8.5.16</version></dependency&......
  • 内存泄漏的几种情况
    1、.Net应用中的内存1.1、托管堆由.NET运行时(CLR)自动管理的内存区域,用于存储对象实例和数组等引用类型数据。在堆上分配的内存会通过垃圾回收器(GC)进行自动回收,对象的创建和销毁都是由GC负责管理。1.2、非托管堆不由CLR控制和管理,通常用于与非托管代码(如C、C++)进行交互、......
  • JUC:java内存模型(如何保证?可见性、原子性、有序性)
    文章目录java内存模型可见性解决方法原子性有序性流水线技术模式之Balking(犹豫)java内存模型JMM即JavaMemoryModel,它定义了主存、工作内存抽象概念,底层对应着CPU寄存器、缓存、硬件内存、CPU指令优化等。JMM体现在以下几个方面:原子性-保证指令不......
  • 内存,寄存器,缓存,cache
    对上面这几个名词认识,但要说对他们的理解,不知道。在项目开发过程中,经常会遇到说什么从缓存读取数据,拷贝到内存,什么值存在寄存器中等等,但都是傻傻分不清。没有自己的理解。下面从volatile关键字引入本节的学习原文链接:https://blog.csdn.net/Goforyouqp/article/details/1313099......