← 返回首页
‘new[]’ array freed with ‘delete’ — CodeQL query help documentation CodeQL docs
CodeQL documentation
CodeQL resources

‘new[]’ array freed with ‘delete’

ID: cpp/new-array-delete-mismatch Kind: problem Security severity: Severity: warning Precision: high Tags: - reliability Query suites: - cpp-security-and-quality.qls

Click to see the query in the CodeQL repository

This rule finds delete expressions that are using a pointer that points to memory allocated using the new[] operator. This should be avoided since it results in undefined behavior, as per §5.3.5 of the ISO/IEC C++ Standard:

“In the first alternative (delete object), the value of the operand of delete may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to a sub-object representing a base class of such an object. If not, the behavior is undefined.”

Besides being formally undefined, there are two practical reasons why this is likely to cause defects. For the first of these, consider what happens when invoking X *p = new X[23]:

  1. Sufficient memory is allocated to hold 23 instances of type X by invoking ::operator new(sizeof(X) * 23).

  2. Each of the 23 instances of X is constructed at its correct place in memory (as if doing a placement new). If delete[] p is subsequently executed, the reverse happens:

  3. The destructor for each of the 23 instances of X is invoked (as if doing an explicit (p + i)->~X()).

  4. The memory allocated by ::operator new is deallocated by invoking ::operator delete(p). By contrast, delete p (without the [] brackets) would generally assume that p points to exactly one instance of X, and only call the destructor for that (although this behavior cannot be relied upon, since the results are formally undefined). The practical result of this is that the destructors for the remaining X instances, which might do crucial things such as freeing resources, will not be called.

There is also a second practical reason why this may cause a defect. In order to call the destructors of the array elements when delete[] is called, the implementation must know the size of array to which p points at deletion time. Bearing in mind that p is a pointer, and carries no array size information in its type, this information would not in general be available unless the implementation somehow stores it when new[] is invoked. There are two common ways in which this is done:

WARNING: This check is an approximation, so some results may not be actual defects in the program. It is not possible in general to compute the values of pointers without running the program with all input data.

Recommendation

Use the delete[] operator when freeing memory allocated with new[].

Example

Record* record = new Record[SIZE]; ... delete record; //record was created using 'new[]', but was freed using 'delete'

References