
The C++ Standard, [expr.delete], paragraph 3 [ISO/IEC 14882-2014], states the following:
In the first alternative (delete object), if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined. In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.
...
Code Block | ||||
---|---|---|---|---|
| ||||
struct Base { virtual ~Base() = default; virtual void f() {} }; struct Derived final : Base {}; void f() { Base *b = new Derived[10]; // ... delete [] b; } |
...
In this compliant solution, the static type of b
is Derived *
, which removes the undefined behavior when indexing into the array as well as when deleting the pointer:.
Code Block | ||||
---|---|---|---|---|
| ||||
struct Base { virtual ~Base() = default; virtual void f() {} }; struct Derived final : Base {}; void f() { Derived *b = new Derived[10]; // ... delete [] b; } |
Risk Assessment
Attempting to destruct a polymorphic object that does not have a virtual
destructor declared results in undefined destroy an array of polymorphic objects through the incorrect static type is undefined behavior. In practice, potential consequences include abnormal program termination and execution and memory leaks.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
EXP51-CPP | Low |
Unlikely |
Medium |
P2 |
L3 |
Automated Detection
Tool | Version | Checker | Description | |||||
---|---|---|---|---|---|---|---|---|
| -analyzer-checker=cplusplus |
Checked with clang -cc1 or (preferably) scan-build | |||||||||
CodeSonar |
| ALLOC.TM | Type Mismatch | ||||||
Helix QAC |
| C++3166 | |||||||
Klocwork |
| CERT.EXPR.DELETE_ARR.BASE_PTR | |||||||
Parasoft C/C++test |
| CERT_CPP-EXP51-a | Do not treat arrays polymorphically | ||||||
Parasoft Insure++ | Runtime detection | ||||||||
Polyspace Bug Finder |
| CERT C++: EXP51-CPP | Checks for delete operator used to destroy downcast object of different type. |
Related Vulnerabilities
Search for other vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
SEI CERT C++ Coding Standard | CTR56-CPP. Do not use pointer arithmetic on polymorphic objects OOP52-CPP. Do not delete a polymorphic object without a virtual destructor |
Bibliography
[ISO/IEC 14882-2014] | Subclause 5.3.5, "Delete" |
...
...