Movatterモバイル変換


[0]ホーム

URL:


CodeQL documentation
CodeQL resources

‘new[]’ array freed with ‘delete’

ID: cpp/new-array-delete-mismatchKind: problemSecurity severity: Severity: warningPrecision: highTags:   - reliabilityQuery suites:   - cpp-security-and-quality.qls

Click to see the query in the CodeQL repository

This rule findsdelete expressions that are using a pointer that points to memory allocated using thenew[] 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 ofdelete may be a null pointer value, a pointer to a non-array object created by a previousnew-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 invokingX*p=newX[23]:

  1. Sufficient memory is allocated to hold23 instances of typeX by invoking::operatornew(sizeof(X)*23).

  2. Each of the23 instances ofX is constructed at its correct place in memory (as if doing aplacement new).Ifdelete[]p is subsequently executed, the reverse happens:

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

  4. The memory allocated by::operatornew is deallocated by invoking::operatordelete(p).By contrast,deletep (without the[] brackets) would generally assume thatp points to exactly one instance ofX, 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 remainingX 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 whendelete[] is called, the implementation must know the size of array to whichp points at deletion time. Bearing in mind thatp 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 whennew[] is invoked. There are two common ways in which this is done:

  • The most common approach is to allocate a small amount of extra memory (aheader) before the start of the array and store the size in it. When invokingdelete[]p, the implementation then just needs to walk back a fixed amount from the passed-in pointer to read the size. The implication of this is thatp itself (the pointer to the first element in the array) isnot the pointer returned by::operatornew, and so it is not safe to call::operatordelete on it. Instead, it should be called on a pointer that points to the start of the header. Invokingdeletep would use the wrong address, with potentially catastrophic results.

  • An alternative, less common, approach is to store a map from pointers to the sizes of the arrays (if any) to which they point. When invokingdelete[]p, the implementation looks up the pointer in the map, invokes the relevant number of destructors, deallocates the memoryand removes the pointer from the map. Ifdeletep is called instead, not only will the relevant number of destructors likely not be called (as previously noted), but the pointer will also likely not be removed from the map. In practical terms, this is potentially less of a serious issue than that posed by the first approach, but it should still be avoided.

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 thedelete[] operator when freeing memory allocated withnew[].

Example

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

References

  • S. Meyers.Effective C++ 3d ed. pp 73-75. Addison-Wesley Professional, 2005.

  • ISO/IEC 14882:2011, Information technology - Programming languages - C++ §5.3.5. International Organization for Standardization, Geneva, Switzerland, 2011.


[8]ページ先頭

©2009-2025 Movatter.jp